CARLA
Loading...
Searching...
No Matches
BlueprintActorFactory.cpp
Go to the documentation of this file.
1// Copyright (c) 2026 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7
13
14#include <util/ue-header-guard-begin.h>
15#include "Json.h"
16#include "JsonUtilities.h"
17#include "Misc/FileHelper.h"
18#include "Misc/Paths.h"
19#include <util/ue-header-guard-end.h>
20
22{
23 // Rebuilt from scratch every episode, otherwise entries accumulate.
24 Definitions.Reset();
25 BlueprintsParams.Reset();
26 LoadBlueprintParametersArrayFromFile("BlueprintParameters.json", BlueprintsParams);
27 // Content packs: <Pack>/Content/Config/BlueprintParameters.json, later
28 // packs override earlier entries with the same Name.
29 for (const FString &PackFile : UCarlaContentPackManager::FindPackCatalogFiles("BlueprintParameters.json"))
30 {
31 TArray<FBlueprintParameters> PackBlueprintsParams;
32 LoadBlueprintParametersArrayFromFile(PackFile, PackBlueprintsParams);
34 [](const FBlueprintParameters &B) { return B.Name; });
35 }
36
38 return Definitions;
39}
40
42 const FTransform &SpawnAtTransform,
43 const FActorDescription &ActorDescription)
44{
45 FActorSpawnResult SpawnResult;
46 if(!IsValid(ActorDescription.Class))
47 {
48 UE_LOG(LogCarla, Error, TEXT("Actor Description Class is null."));
49 SpawnResult.Status = EActorSpawnResultStatus::InvalidDescription;
50 return SpawnResult;
51 }
52
53 AActor* SpawnedActor = GetWorld()->SpawnActor<AActor>(ActorDescription.Class, SpawnAtTransform);
54 SpawnResult.Actor = SpawnedActor;
55
56 if(SpawnedActor == nullptr)
57 {
58 SpawnResult.Status = EActorSpawnResultStatus::Collision;
59 return SpawnResult;
60 }
61
62 if(PostProcessBlueprint(SpawnedActor, ActorDescription))
63 {
64 SpawnResult.Status = EActorSpawnResultStatus::Success;
65 return SpawnResult;
66 }
67
68 SpawnResult.Status = EActorSpawnResultStatus::UnknownError;
69 return SpawnResult;
70}
71
72void ABlueprintActorFactory::ReleaseContentPack(const FString &MountPoint)
73{
74 Definitions.RemoveAll([&](const FActorDefinition &D) { return DefinitionReferencesPath(D, MountPoint); });
75 BlueprintsParams.RemoveAll([&](const FBlueprintParameters &B) { return B.Path.StartsWith(MountPoint); });
76}
77
79{
80 TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);
81 JsonObject->SetStringField(TEXT("Name"), BlueprintParams.Name);
82 JsonObject->SetStringField(TEXT("Path"), BlueprintParams.Path);
83
84 return JsonObject;
85}
86
87FString ABlueprintActorFactory::FBlueprintParametersArrayToJson(const TArray<FBlueprintParameters>& BlueprintParamsArray)
88{
89 TArray<TSharedPtr<FJsonValue>> JsonArray;
90
91 for (const FBlueprintParameters& BlueprintParams : BlueprintParamsArray)
92 {
93 // Convert each FBlueprintParameters to a JSON object
94 TSharedPtr<FJsonObject> JsonObject = FBlueprintParametersToJsonObject(BlueprintParams);
95 JsonArray.Add(MakeShareable(new FJsonValueObject(JsonObject)));
96 }
97
98 // Convert the array of JSON objects into a single JSON object
99 TSharedRef<FJsonObject> RootObject = MakeShareable(new FJsonObject);
100 RootObject->SetArrayField(TEXT("Blueprints"), JsonArray);
101
102 // Serialize the JSON object into an FString
103 FString OutputString;
104 TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&OutputString);
105 FJsonSerializer::Serialize(RootObject, Writer);
106
107 return OutputString;
108}
109
110void ABlueprintActorFactory::SaveBlueprintParametersArrayToFile(const TArray<FBlueprintParameters>& BlueprintParametersArray, const FString& FileName)
111{
112 FString FilePath = FPaths::ProjectContentDir() + TEXT("Carla/Config/") + FileName;
113 // Convert the array to an FString in JSON format
114 FString JsonContent = FBlueprintParametersArrayToJson(BlueprintParametersArray);
115
116 // Save the JSON to a file
117 if (FFileHelper::SaveStringToFile(JsonContent, *FilePath))
118 {
119 UE_LOG(LogCarla, Log, TEXT("JSON file successfully saved at: %s"), *FilePath);
120 }
121 else
122 {
123 UE_LOG(LogCarla, Error, TEXT("Failed to save JSON file at: %s"), *FilePath);
124 }
125}
126
127bool ABlueprintActorFactory::JsonToFBlueprintParameters(const TSharedPtr<FJsonObject> JsonObject, FBlueprintParameters& OutBlueprintParams)
128{
129 if (!JsonObject.IsValid()) return false;
130
131 JsonObject->TryGetStringField(TEXT("Name"), OutBlueprintParams.Name);
132 JsonObject->TryGetStringField(TEXT("Path"), OutBlueprintParams.Path);
133
134 return true;
135}
136
137bool ABlueprintActorFactory::JsonToFBlueprintParametersArray(const FString& JsonString, TArray<FBlueprintParameters>& OutBlueprintParamsArray)
138{
139 TSharedPtr<FJsonObject> RootObject;
140 TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(JsonString);
141
142 if (!FJsonSerializer::Deserialize(Reader, RootObject) || !RootObject.IsValid())
143 {
144 UE_LOG(LogCarla, Error, TEXT("Failed to parse JSON."));
145 return false;
146 }
147
148 // Get the "Blueprints" array from the JSON root object
149 const TArray<TSharedPtr<FJsonValue>>* BlueprintsArray;
150 if (RootObject->TryGetArrayField(TEXT("Blueprints"), BlueprintsArray))
151 {
152 OutBlueprintParamsArray.Empty();
153 for (const TSharedPtr<FJsonValue>& BlueprintValue : *BlueprintsArray)
154 {
155 TSharedPtr<FJsonObject> BlueprintObject = BlueprintValue->AsObject();
156 if (BlueprintObject.IsValid())
157 {
158 FBlueprintParameters BlueprintParams;
159 if (JsonToFBlueprintParameters(BlueprintObject, BlueprintParams))
160 {
161 OutBlueprintParamsArray.Add(BlueprintParams);
162 }
163 }
164 }
165 }
166
167 return true;
168}
169
170void ABlueprintActorFactory::LoadBlueprintParametersArrayFromFile(const FString& FileName, TArray<FBlueprintParameters>& OutBlueprintParamsArray)
171{
172 FString JsonString;
173 // A relative name is resolved against the project catalog dir; an absolute
174 // path (content pack catalogs) is used as is.
175 FString FilePath = FPaths::IsRelative(FileName)
176 ? FPaths::ProjectContentDir() + TEXT("Carla/Config/") + FileName
177 : FileName;
178 FString JsonContent;
179
180 // Load the JSON file content into an FString
181 if (FFileHelper::LoadFileToString(JsonContent, *FilePath))
182 {
183 // Parse the JSON and populate the TArray<FBlueprintParameters>
184 if (JsonToFBlueprintParametersArray(JsonContent, OutBlueprintParamsArray))
185 {
186 UE_LOG(LogCarla, Log, TEXT("Blueprint parameters loaded successfully from %s"), *FilePath);
187 }
188 else
189 {
190 UE_LOG(LogCarla, Error, TEXT("Failed to parse Blueprint parameters from %s"), *FilePath);
191 }
192 }
193 else
194 {
195 UE_LOG(LogCarla, Error, TEXT("Failed to load file: %s"), *FilePath);
196 }
197}
static bool IsValid(const ACarlaWheeledVehicle *Vehicle)
TArray< FBlueprintParameters > BlueprintsParams
virtual TArray< FActorDefinition > GetDefinitions() override
Retrieve the definitions of the static mesh actor.
static FString FBlueprintParametersArrayToJson(const TArray< FBlueprintParameters > &BlueprintParamsArray)
TArray< FActorDefinition > Definitions
static void LoadBlueprintParametersArrayFromFile(const FString &FileName, TArray< FBlueprintParameters > &OutBlueprintParamsArray)
virtual FActorSpawnResult SpawnActor(const FTransform &SpawnAtTransform, const FActorDescription &ActorDescription) override
Spawn an actor based on ActorDescription and Transform.
static bool JsonToFBlueprintParametersArray(const FString &JsonString, TArray< FBlueprintParameters > &OutBlueprintParamsArray)
static TSharedPtr< FJsonObject > FBlueprintParametersToJsonObject(const FBlueprintParameters &BlueprintParams)
static bool JsonToFBlueprintParameters(const TSharedPtr< FJsonObject > JsonObject, FBlueprintParameters &OutBlueprintParams)
virtual void ReleaseContentPack(const FString &MountPoint) override
Drop every cached definition, parameter and loaded asset that refers to content under MountPoint ("/<...
bool PostProcessBlueprint(AActor *SpawnedActor, const FActorDescription &BlueprintParams)
static void SaveBlueprintParametersArrayToFile(const TArray< FBlueprintParameters > &BlueprintParamsArray, const FString &FileName)
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 void MakeBlueprintDefinitions(const TArray< FBlueprintParameters > &ParameterArray, TArray< FActorDefinition > &Definitions)
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.
TSubclassOf< AActor > Class
Class of the actor to be spawned.
Result of an actor spawn function.
EActorSpawnResultStatus Status