22#include "Kismet/KismetSystemLibrary.h"
23#include "Engine/GameViewportClient.h"
24#include "GameFramework/Actor.h"
25#include "Engine/Engine.h"
26#include "UObject/Class.h"
27#include "Engine/World.h"
32static const FString
WALKER_ASSET_PATH =
"/Game/Agrarsense/Data/Walkers/WalkerActorAssetMap";
33static const FString
PROP_ASSET_PATH =
"/Game/Agrarsense/Data/Props/PropActorAssetMap";
52 FString ActorName, FString ActorID,
53 bool RandomZRotation,
bool SnapToGround)
63 TSubclassOf<AActor> ActorClass = ActorAssetData ? ActorAssetData->
ActorAsset.
Actor :
nullptr;
65 AActor* SpawnedActor =
TrySpawnActor(ActorClass,
Transform, ActorName, ActorID, SnapToGround, RandomZRotation);
79 Data.
Actor = InstancedActor;
87 FTransform SpawnTransform,
const FString& ActorName,
88 const FString& ActorID,
bool SnapAboveGround,
89 const float AboveOffset,
const bool DestroyOverlappingActors)
99 TSubclassOf<AActor> ActorClass = ActorAssetData ? ActorAssetData->
ActorAsset.
Actor :
nullptr;
101 ESpawnActorCollisionHandlingMethod SpawnCollisionHandling = ESpawnActorCollisionHandlingMethod::Undefined;
105 SpawnCollisionHandling = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
108 FString ID = ActorID;
114 AActor* SpawnedActor =
TrySpawnActor(ActorClass, SpawnTransform, ActorName, ID,
false,
false, SpawnCollisionHandling);
122 SpawnTransform = SpawnedActor->GetTransform();
130 Vehicle->TeleportTo(SpawnTransform.GetLocation(), SpawnTransform.GetRotation().Rotator());
132 if (DestroyOverlappingActors)
148 FString ActorName, FString ActorID,
149 bool RandomZRotation,
bool SnapToGround)
159 TSubclassOf<AActor> ActorClass = ActorAssetData ? ActorAssetData->
ActorAsset.
Actor :
nullptr;
161 AActor* SpawnedActor =
TrySpawnActor(ActorClass,
Transform, ActorName, ActorID, SnapToGround, RandomZRotation);
167 InstancedActorData.
Actor = InstancedActor;
180 Data.
Actor = InstancedActor;
188 const FString& ActorID,
bool StartAutomatically)
198 TSubclassOf<AActor> ActorClass = ActorAssetData ? ActorAssetData->
ActorAsset.
Actor :
nullptr;
200 FTransform StartTransform;
201 auto& Transforms = Parameters.
Points;
203 if (!Transforms.IsEmpty())
207 SimulatorLog::Log(
"Failed to spawn FollowPath Walker due to insufficient path points.");
210 StartTransform = Transforms[0];
213 FString ID = ActorID;
219 AActor* SpawnedActor =
TrySpawnActorDeferred(ActorClass, StartTransform, ActorName, ID,
false,
false);
225 Walker->SetWalkerParameters(Parameters);
226 Walker->SetIgnoreInput(!StartAutomatically);
228 SpawnedActor->FinishSpawning(StartTransform);
235 FString ActorName, FString ActorID,
236 bool SnapToGround,
bool RandomZRotation, ESpawnActorCollisionHandlingMethod CollisionMethod)
238 if (!IsInGameThread())
241 UE_LOG(LogTemp, Warning, TEXT(
"AssetLibrary.cpp: Attempting to spawn actor from a background thread. This is not allowed."));
249 UE_LOG(LogTemp, Warning, TEXT(
"AssetLibrary.cpp: ActorClass is nullptr! Cannot spawn actor."));
254 UWorld* World =
nullptr;
255 if (GEngine && GEngine->GameViewport)
257 World = GEngine->GameViewport->GetWorld();
266 AActor* SpawnedActor = World->SpawnActorDeferred<AActor>(ActorClass,
Transform,
nullptr,
nullptr, CollisionMethod);
273 Transform = SpawnedActor->GetTransform();
278 float RotationAngle = FMath::FRandRange(0.0f, 360.0f);
279 Transform.SetRotation(FQuat::MakeFromEuler(FVector(0.0f, 0.0f, RotationAngle)));
283 if (SpawnedActor && SpawnedActor->GetClass()->ImplementsInterface(UActorInformation::StaticClass()))
285 IActorInformation::Execute_SetActorIDAndName(SpawnedActor, ActorName, ActorID);
295AActor*
UAssetLibrary::TrySpawnActorDeferred(TSubclassOf<AActor> ActorClass, FTransform& Transform, FString ActorName, FString ActorID,
bool SnapToGround,
bool RandomZRotation, ESpawnActorCollisionHandlingMethod CollisionMethod)
297 if (!IsInGameThread())
300 UE_LOG(LogTemp, Warning, TEXT(
"AssetLibrary.cpp: Attempting to spawn actor from a background thread. This is not allowed."));
308 UE_LOG(LogTemp, Warning, TEXT(
"AssetLibrary.cpp: ActorClass is nullptr! Cannot spawn actor."));
313 UWorld* World =
nullptr;
314 if (GEngine && GEngine->GameViewport)
316 World = GEngine->GameViewport->GetWorld();
325 AActor* SpawnedActor = World->SpawnActorDeferred<AActor>(ActorClass,
Transform,
nullptr,
nullptr, CollisionMethod);
332 Transform = SpawnedActor->GetTransform();
337 float RotationAngle = FMath::FRandRange(0.0f, 360.0f);
338 Transform.SetRotation(FQuat::MakeFromEuler(FVector(0.0f, 0.0f, RotationAngle)));
342 if (SpawnedActor && SpawnedActor->GetClass()->ImplementsInterface(UActorInformation::StaticClass()))
344 IActorInformation::Execute_SetActorIDAndName(SpawnedActor, ActorName, ActorID);
353 UWorld* World =
nullptr;
354 if (GEngine && GEngine->GameViewport)
356 World = GEngine->GameViewport->GetWorld();
359 if (!World || !SpawnedActor)
366 SpawnedActor->GetActorBounds(
true, Origin, BoxExtent);
368 float SphereRadius = BoxExtent.GetMax();
370 TArray<AActor*> OverlappingActors;
371 UKismetSystemLibrary::SphereOverlapActors(World, SpawnedActor->GetTransform().GetLocation(), SphereRadius, {},
nullptr, {}, OverlappingActors);
373 for (AActor* OverlappingActor : OverlappingActors)
375 if (OverlappingActor && OverlappingActor != SpawnedActor)
377 if (OverlappingActor->IsA(AWalker::StaticClass()) ||
378 OverlappingActor->IsA(AInstancedActor::StaticClass()) ||
379 OverlappingActor->IsA(AVehicle::StaticClass()))
381 OverlappingActor->Destroy();
391 return !VehicleData.
Vehicle.IsValid();
411 int32 RandomIndex = FMath::RandRange(0,
FoliageKeys.Num() - 1);
415 return RandomFoliageType;
422 return !ActorData.
Actor.IsValid();
425 TArray<AInstancedActor*> ValidActors;
430 if (ActorData.
Actor.IsValid())
432 ValidActors.Add(ActorData.
Actor.Get());
453 int32 RandomIndex = FMath::RandRange(0,
PropKeys.Num() - 1);
454 RandomPropType =
PropKeys[RandomIndex];
457 return RandomPropType;
464 return !ActorData.
Actor.IsValid();
467 TArray<AInstancedActor*> ValidActors;
472 if (ActorData.
Actor.IsValid())
474 ValidActors.Add(ActorData.
Actor.Get());
490 SpawnedWalkers.RemoveAll([](
const TWeakObjectPtr<AWalker>& ActorData)
492 return !ActorData.IsValid();
495 TArray<AWalker*> ValidWalkers;
500 AWalker* WalkerPtr = ActorData.Get();
503 ValidWalkers.Add(WalkerPtr);
514 if (WalkersActors.IsEmpty())
527 WalkersActors.Empty();
529 FString Message = FString::Printf(TEXT(
"Destroyed all %d Walkers."), WalkersActors.Num());
539 VehicleDataAsset = Cast<UVehicleActorAssetMapDataAsset>(VehicleActorAssetMap.TryLoad());
558 FoliageTypeMap = UEnumUtilities::CreateEnumStringMap<EFoliageTypes>(
"/Script/Agrarsense.EFoliageTypes");
578 PropTypeMap = UEnumUtilities::CreateEnumStringMap<EPropTypes>(
"/Script/Agrarsense.EPropTypes");
static const FString PROP_ASSET_PATH
static const FString VEHICLE_ASSET_PATH
static const FString FOLIAGE_ASSET_PATH
static const FString WALKER_ASSET_PATH
void SetTypeAndModel(const FString &Type, const FString &Model)
static void Log(const FString &Message, bool LogToTextFile=true, bool LogToROS=true)
static TWeakObjectPtr< UFoliageActorAssetMapDataAsset > FoliageActorAssetMapDataAsset
static UWalkerActorAssetMapDataAsset * GetWalkerActorAssetMapDataAsset()
static TArray< AInstancedActor * > GetAllAddedPropActors()
static void SetupWalkerDataAsset()
static TArray< FInstancedActorData > SpawnedPropActors
static TMap< EFoliageTypes, FString > FoliageTypeMap
static AVehicle * SpawnVehicle(EVehicleTypes VehicleType, FTransform SpawnTransform, const FString &ActorName, const FString &ActorID, bool SnapAboveGround=false, float AboveOffset=150.0f, bool DestroyOverlappingActors=false)
static void DestroyAllWalkers()
static AActor * TrySpawnActorDeferred(TSubclassOf< AActor > ActorClass, FTransform &Transform, FString ActorName, FString ActorID, bool SnapToGround, bool RandomZRotation, ESpawnActorCollisionHandlingMethod CollisionMethod=ESpawnActorCollisionHandlingMethod::Undefined)
static TWeakObjectPtr< UVehicleActorAssetMapDataAsset > VehicleDataAsset
static void SetupVehicleDataAsset()
static EFoliageTypes GetRandomFoliageType()
static void DestroyOverlappingActorsSphere(AActor *SpawnedActor)
static TArray< FVehicleData > GetSpawnedVehicles()
static TArray< EPropTypes > PropKeys
static TArray< EFoliageTypes > FoliageKeys
static TMap< EPropTypes, FString > PropTypeMap
static TArray< AInstancedActor * > GetAllAddedFoliageActors()
static TArray< AWalker * > GetAllWalkers()
static void SetupPropDataAsset()
static TWeakObjectPtr< UPropActorAssetMapDataAsset > PropActorAssetMapDataAsset
static AActor * SpawnProp(EPropTypes PropType, FTransform Transform, FString ActorName="", FString ActorID="", bool RandomZRotation=false, bool SnapToGround=false)
static void SetupFoliageDataAsset()
static TWeakObjectPtr< UWalkerActorAssetMapDataAsset > WalkerActorAssetMapDataAsset
static AActor * TrySpawnActor(TSubclassOf< AActor > ActorClass, FTransform &Transform, FString ActorName, FString ActorID, bool SnapToGround, bool RandomZRotation, ESpawnActorCollisionHandlingMethod CollisionMethod=ESpawnActorCollisionHandlingMethod::Undefined)
static AWalker * SpawnWalker(FWalkerParameters Parameters, const FString &ActorName="", const FString &ActorID="", bool StartAutomatically=true)
static EPropTypes GetRandomPropType()
static TArray< FVehicleData > SpawnedVehicles
static TArray< TWeakObjectPtr< AWalker > > SpawnedWalkers
static UPropActorAssetMapDataAsset * GetPropActorAssetMapDataAsset()
static UFoliageActorAssetMapDataAsset * GetFoliageActorAssetMapDataAsset()
static AActor * SpawnFoliage(EFoliageTypes FoliageType, FTransform Transform, FString ActorName="", FString ActorID="", bool RandomZRotation=true, bool SnapToGround=true)
static TArray< FInstancedActorData > AddedFoliageActors
static FString ConvertVehicleTypeToString(EVehicleTypes VehicleType)
static FString ConvertWalkerTypeToString(EWalkerType WalkerType)
static bool SnapActorAboveGround(AActor *Actor, float AboveOffset=50.0f)
static bool SnapActorToGround(AActor *Actor, float StartZOffset=600.0f, float EndZOffset=600.0f)
TSubclassOf< AActor > Actor
TWeakObjectPtr< AInstancedActor > Actor
EVehicleTypes VehicleType
TWeakObjectPtr< AVehicle > Vehicle
EWalkerAction WalkerAction
TArray< FTransform > Points