15#include <util/ue-header-guard-begin.h>
17#include "JsonUtilities.h"
18#include "Misc/FileHelper.h"
19#include "Misc/Paths.h"
20#include <util/ue-header-guard-end.h>
32 TArray<FPedestrianParameters> PackWalkersParams;
43 const FTransform &SpawnAtTransform,
49 UE_LOG(LogCarla, Error, TEXT(
"Actor Description Class is null."));
50 SpawnResult.
Status = EActorSpawnResultStatus::InvalidDescription;
54 AActor* SpawnedActor = GetWorld()->SpawnActor<
AActor>(ActorDescription.
Class, SpawnAtTransform);
55 SpawnResult.
Actor = SpawnedActor;
57 if(SpawnedActor ==
nullptr)
59 SpawnResult.
Status = EActorSpawnResultStatus::Collision;
65 AWalkerBase* Walker = Cast<AWalkerBase>(SpawnedActor);
69 TEXT(
"use_wheelchair"), ActorDescription.
Variations,
false);
80 SpawnResult.
Status = EActorSpawnResultStatus::Success;
84 SpawnResult.
Status = EActorSpawnResultStatus::UnknownError;
92 return W.
Class.ToSoftObjectPath().ToString().StartsWith(MountPoint);
98 TSharedPtr<FJsonObject> JsonObject = MakeShareable(
new FJsonObject);
99 JsonObject->SetStringField(TEXT(
"Id"), WalkerParams.
Id);
100 JsonObject->SetStringField(TEXT(
"Class"), WalkerParams.
Class.ToSoftObjectPath().ToString());
102 FString GenderString;
103 switch(WalkerParams.
Gender)
105 case EPedestrianGender::Other:
106 GenderString = FString(
"Other");
108 case EPedestrianGender::Female:
109 GenderString = FString(
"Female");
111 case EPedestrianGender::Male:
112 GenderString = FString(
"Male");
115 GenderString = FString(
"INVALID");
118 JsonObject->SetStringField(TEXT(
"Gender"), GenderString);
121 switch(WalkerParams.
Age)
123 case EPedestrianAge::Child:
124 AgeString = FString(
"Child");
126 case EPedestrianAge::Teenager:
127 AgeString = FString(
"Teenager");
129 case EPedestrianAge::Adult:
130 AgeString = FString(
"Adult");
132 case EPedestrianAge::Elderly:
133 AgeString = FString(
"Elderly");
136 AgeString = FString(
"INVALID");
139 JsonObject->SetStringField(TEXT(
"Age"), AgeString);
142 TArray<TSharedPtr<FJsonValue>> SpeedArray;
143 for (
const float& Speed : WalkerParams.
Speed)
145 TSharedPtr<FJsonObject> SpeedObject = MakeShareable(
new FJsonObject);
146 SpeedObject->SetNumberField(TEXT(
"Speed"), Speed);
147 SpeedArray.Add(MakeShareable(
new FJsonValueObject(SpeedObject)));
149 JsonObject->SetArrayField(TEXT(
"Speeds"), SpeedArray);
151 JsonObject->SetNumberField(TEXT(
"Generation"), WalkerParams.
Generation);
153 JsonObject->SetStringField(TEXT(
"SpecialType"), WalkerParams.
SpecialType);
155 JsonObject->SetBoolField(TEXT(
"CanUseWheelChair"), WalkerParams.
bCanUseWheelChair);
162 TArray<TSharedPtr<FJsonValue>> JsonArray;
168 JsonArray.Add(MakeShareable(
new FJsonValueObject(JsonObject)));
172 TSharedRef<FJsonObject> RootObject = MakeShareable(
new FJsonObject);
173 RootObject->SetArrayField(TEXT(
"Walkers"), JsonArray);
176 FString OutputString;
177 TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&OutputString);
178 FJsonSerializer::Serialize(RootObject, Writer);
185 FString FilePath = FPaths::ProjectContentDir() + TEXT(
"Carla/Config/") + FileName;
190 if (FFileHelper::SaveStringToFile(JsonContent, *FilePath))
192 UE_LOG(LogCarla, Log, TEXT(
"JSON file successfully saved at: %s"), *FilePath);
196 UE_LOG(LogCarla, Error, TEXT(
"Failed to save JSON file at: %s"), *FilePath);
202 if (!JsonObject.IsValid())
return false;
204 JsonObject->TryGetStringField(TEXT(
"Id"), OutWalkerParams.
Id);
210 JsonObject->TryGetStringField(TEXT(
"Class"), ClassPath);
211 OutWalkerParams.
Class = TSoftClassPtr<ACharacter>(FSoftObjectPath(ClassPath));
213 FString GenderString;
214 JsonObject->TryGetStringField(TEXT(
"Gender"), GenderString);
216 if(GenderString == FString(
"Other")){
217 OutWalkerParams.
Gender = EPedestrianGender::Other;
219 else if(GenderString == FString(
"Female"))
221 OutWalkerParams.
Gender = EPedestrianGender::Female;
223 else if(GenderString == FString(
"Male"))
225 OutWalkerParams.
Gender = EPedestrianGender::Male;
229 OutWalkerParams.
Gender = EPedestrianGender::INVALID;
233 JsonObject->TryGetStringField(TEXT(
"Age"), AgeString);
235 if(AgeString == FString(
"Child")){
236 OutWalkerParams.
Age = EPedestrianAge::Child;
238 else if(AgeString == FString(
"Teenager"))
240 OutWalkerParams.
Age = EPedestrianAge::Teenager;
242 else if(AgeString == FString(
"Adult"))
244 OutWalkerParams.
Age = EPedestrianAge::Adult;
246 else if(AgeString == FString(
"Elderly"))
248 OutWalkerParams.
Age = EPedestrianAge::Elderly;
252 OutWalkerParams.
Age = EPedestrianAge::INVALID;
256 const TArray<TSharedPtr<FJsonValue>>* SpeedsArray;
257 if (JsonObject->TryGetArrayField(TEXT(
"Speeds"), SpeedsArray))
259 OutWalkerParams.
Speed.Empty();
260 for (
const TSharedPtr<FJsonValue>& SpeedValue : *SpeedsArray)
262 TSharedPtr<FJsonObject> SpeedObject = SpeedValue->AsObject();
263 if (SpeedObject.IsValid())
266 Speed = SpeedObject->GetNumberField(TEXT(
"Speed"));
267 OutWalkerParams.
Speed.Add(Speed);
272 JsonObject->TryGetNumberField(TEXT(
"Generation"), OutWalkerParams.
Generation);
276 bool bCanUseWheelChair =
false;
277 if (JsonObject->TryGetBoolField(TEXT(
"CanUseWheelChair"), bCanUseWheelChair))
282 JsonObject->TryGetStringField(TEXT(
"SpecialType"), OutWalkerParams.
SpecialType);
289 TSharedPtr<FJsonObject> RootObject;
290 TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(JsonString);
292 if (!FJsonSerializer::Deserialize(Reader, RootObject) || !RootObject.IsValid())
294 UE_LOG(LogCarla, Error, TEXT(
"Failed to parse JSON."));
299 const TArray<TSharedPtr<FJsonValue>>* WalkersArray;
300 if (RootObject->TryGetArrayField(TEXT(
"Walkers"), WalkersArray))
302 OutWalkerParamsArray.Empty();
303 for (
const TSharedPtr<FJsonValue>& WalkerValue : *WalkersArray)
305 TSharedPtr<FJsonObject> WalkerObject = WalkerValue->AsObject();
306 if (WalkerObject.IsValid())
311 OutWalkerParamsArray.Add(WalkerParams);
325 FString FilePath = FPaths::IsRelative(FileName)
326 ? FPaths::ProjectContentDir() + TEXT(
"Carla/Config/") + FileName
331 if (FFileHelper::LoadFileToString(JsonContent, *FilePath))
336 UE_LOG(LogCarla, Log, TEXT(
"Walker parameters loaded successfully from %s"), *FilePath);
340 UE_LOG(LogCarla, Error, TEXT(
"Failed to parse Walker parameters from %s"), *FilePath);
345 UE_LOG(LogCarla, Error, TEXT(
"Failed to load file: %s"), *FilePath);
static bool IsValid(const ACarlaWheeledVehicle *Vehicle)
static bool DefinitionReferencesPath(const FActorDefinition &Definition, const FString &MountPoint)
True when the definition's class or any attribute/variation value points at content under MountPoint.
static FString FWalkerParametersArrayToJson(const TArray< FPedestrianParameters > &WalkerParamsArray)
TArray< FPedestrianParameters > WalkersParams
static TSharedPtr< FJsonObject > FWalkerParametersToJsonObject(const FPedestrianParameters &WalkerParams)
static void LoadWalkerParametersArrayFromFile(const FString &FileName, TArray< FPedestrianParameters > &OutWalkerParamsArray)
virtual TArray< FActorDefinition > GetDefinitions() override
Retrieve the definitions of the static mesh actor.
virtual FActorSpawnResult SpawnActor(const FTransform &SpawnAtTransform, const FActorDescription &ActorDescription) override
Spawn an actor based on ActorDescription and Transform.
bool PostProcessWalker(AActor *SpawnedActor, const FActorDescription &WalkerParams)
TArray< FActorDefinition > Definitions
static void SaveWalkerParametersArrayToFile(const TArray< FPedestrianParameters > &WalkerParamsArray, const FString &FileName)
static bool JsonToFWalkerParametersArray(const FString &JsonString, TArray< FPedestrianParameters > &OutWalkerParamsArray)
virtual void ReleaseContentPack(const FString &MountPoint) override
Drop every cached definition, parameter and loaded asset that refers to content under MountPoint ("/<...
static bool JsonToFWalkerParameters(const TSharedPtr< FJsonObject > JsonObject, FPedestrianParameters &OutWalkerParams)
void AttachWheelchair()
Attach the wheelchair prop to the walker and switch the walker to the sitting animation.
bool bUsesWheelChair
Whether this walker was spawned riding a wheelchair (the "use_wheelchair" user attribute).
static void MakePedestrianDefinitions(const TArray< FPedestrianParameters > &ParameterArray, TArray< FActorDefinition > &Definitions)
static bool RetrieveActorAttributeToBool(const FString &Id, const TMap< FString, FActorAttribute > &Attributes, bool Default)
static void MergeCatalog(TArray< T > &Into, const TArray< T > &From, KeyFn Key)
Merge catalog entries: an entry whose key already exists replaces it in place (later files override b...
static TArray< FString > FindPackCatalogFiles(const FString &RelativeName)
<ContentDir>/Config/<RelativeName> of every mounted pack where the file exists, in mount order (later...
A definition of a Carla Actor with all the variation and attributes.
A description of a Carla Actor with all its variation.
TMap< FString, FActorAttribute > Variations
User selected variations of the actor.
TSubclassOf< AActor > Class
Class of the actor to be spawned.
Result of an actor spawn function.
EActorSpawnResultStatus Status
TSoftClassPtr< ACharacter > Class