// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "MassCrowdRepresentationActorManagement.h"
#include "SampleMassCrowdRepresentationActorManagement.generated.h"
struct FMassEntityManager;
class UMassCrowdSpawnerSubsystem;
/**
* Overridden actor management fro forsty specific
*/
UCLASS(meta = (DisplayName = "Vrealmatic Crowd Visualization"))
class VREALMATICSAMPLE_API USampleMassCrowdRepresentationActorManagement : public UMassCrowdRepresentationActorManagement
{
GENERATED_BODY()
/**
* Method that will be bound to a delegate used post-spawn to notify and let the requester configure the actor
* @param SpawnRequestHandle the handle of the spawn request that was just spawned
* @param SpawnRequest of the actor that just spawned
* @param EntitySubsystem to use to retrieve the mass agent fragments
* @return The action to take on the spawn request, either keep it there or remove it.
*/
virtual EMassActorSpawnRequestAction OnPostActorSpawn(const FMassActorSpawnRequestHandle& SpawnRequestHandle, FConstStructView SpawnRequest, FMassEntityManager* EntitySubsystem) const override;
/**
* Teleports the actor at the specified transform by preserving its velocity and without collision.
* The destination will be adjusted to fit an existing capsule.
* @param Transform is the new actor's transform
* @param Actor is the actual actor to teleport
* @param CommandBuffer to queue up anything that is thread sensitive
*/
virtual void TeleportActor(const FTransform& Transform, AActor& Actor, FMassCommandBuffer& CommandBuffer) const override;
};
// Copyright Epic Games, Inc. All Rights Reserved.
#include "Mass/SampleMassCrowdRepresentationActorManagement.h"
#include "IMassCrowdActor.h"
#include "MassEntityManager.h"
#include "MassCrowdSpawnerSubsystem.h"
#include "Components/CapsuleComponent.h"
#include "Character/OccupantCharacter.h"
#include "Enum/MovementAction.h"
EMassActorSpawnRequestAction USampleMassCrowdRepresentationActorManagement::OnPostActorSpawn(const FMassActorSpawnRequestHandle& SpawnRequestHandle, FConstStructView SpawnRequest, FMassEntityManager* EntitySubsystem) const
{
check(EntitySubsystem);
const EMassActorSpawnRequestAction Result = Super::OnPostActorSpawn(SpawnRequestHandle, SpawnRequest, EntitySubsystem);
const FMassActorSpawnRequest& MassActorSpawnRequest = SpawnRequest.Get<FMassActorSpawnRequest>();
checkf(MassActorSpawnRequest.SpawnedActor, TEXT("Expecting valid spawned actor"));
if (IMassCrowdActorInterface* MassCrowdActor = Cast<IMassCrowdActorInterface>(MassActorSpawnRequest.SpawnedActor))
{
MassCrowdActor->OnGetOrSpawn(EntitySubsystem, MassActorSpawnRequest.MassAgent);
//MassCrowdActor->SetMovementMode(EMovementMode::MOVE_Custom);
}
return Result;
}
void USampleMassCrowdRepresentationActorManagement::TeleportActor(const FTransform& Transform, AActor& Actor, FMassCommandBuffer& CommandBuffer) const
{
FTransform RootTransform = Transform;
if (const UCapsuleComponent* CapsuleComp = Actor.FindComponentByClass<UCapsuleComponent>())
{
const FVector HalfHeight(0.0f, 0.0f, CapsuleComp->GetScaledCapsuleHalfHeight());
RootTransform.AddToTranslation(HalfHeight);
const FVector RootLocation = RootTransform.GetLocation();
const FVector SweepOffset(0.0f, 0.0f, 20.0f);
const FVector Start = RootLocation + SweepOffset;
const FVector End = RootLocation - SweepOffset;
FCollisionQueryParams Params;
Params.AddIgnoredActor(&Actor);
FHitResult OutHit;
if (Actor.GetWorld()->SweepSingleByChannel(OutHit, Start, End, Transform.GetRotation(), CapsuleComp->GetCollisionObjectType(), CapsuleComp->GetCollisionShape(), Params))
{
if (IMassCrowdActorInterface* MassCrowdActor = Cast(&Actor))
{
MassCrowdActor->SetAdditionalMeshOffset(RootTransform.GetLocation().Z - OutHit.Location.Z);
}
if (AOccupantCharacter* Character = Cast<AOccupantCharacter>(&Actor))
{
// Now you can access properties and methods of AOccupantCharacter
// ...
}
RootTransform.SetLocation(OutHit.Location);
}
}
// Skip Super(UMassCrowdRepresentationActorManagement) because we already done that work here and we needed to know the offset to send to the feet IK logic
UMassRepresentationActorManagement::TeleportActor(RootTransform, Actor, CommandBuffer);
}