10#include "FileHelpers.h"
12#include "Misc/FileHelper.h"
13#include "JsonObject.h"
14#include "JsonSerializer.h"
15#include "UObject/ConstructorHelpers.h"
16#include "Runtime/Engine/Classes/Kismet/GameplayStatics.h"
17#include "Engine/StreamableManager.h"
18#include "Engine/StaticMeshActor.h"
20#include "Engine/DecalActor.h"
21#include "Components/DecalComponent.h"
33#if WITH_EDITORONLY_DATA
35 static ConstructorHelpers::FObjectFinder<UBlueprint> RoadPainterBlueprint(TEXT(
36 "Blueprint'/Game/Carla/Blueprints/LevelDesign/RoadPainterPreset.RoadPainterPreset'"));
41 DecalNamesMap.Add(
"dirt1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDirt_01.DI_RoadDirt_01'");
42 DecalNamesMap.Add(
"dirt2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDirt_02.DI_RoadDirt_02'");
43 DecalNamesMap.Add(
"dirt3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDirt_03.DI_RoadDirt_03'");
44 DecalNamesMap.Add(
"dirt4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDirt_04.DI_RoadDirt_04'");
45 DecalNamesMap.Add(
"dirt5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDirt_05.DI_RoadDirt_05'");
48 DecalNamesMap.Add(
"drip1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDrip_01.DI_RoadDrip_01'");
49 DecalNamesMap.Add(
"drip2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDrip_02.DI_RoadDrip_02'");
50 DecalNamesMap.Add(
"drip3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadDrip_03.DI_RoadDrip_03'");
53 DecalNamesMap.Add(
"roadline1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadLine_01.DI_RoadLine_01'");
54 DecalNamesMap.Add(
"roadline2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadLine_02.DI_RoadLine_02'");
55 DecalNamesMap.Add(
"roadline3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadLine_03.DI_RoadLine_03'");
56 DecalNamesMap.Add(
"roadline4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadLine_04.DI_RoadLine_04'");
57 DecalNamesMap.Add(
"roadline5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_RoadLine_05.DI_RoadLine_05'");
60 DecalNamesMap.Add(
"tiremark1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_TireMark_01.DI_TireMark_01'");
61 DecalNamesMap.Add(
"tiremark2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_TireMark_02.DI_TireMark_02'");
62 DecalNamesMap.Add(
"tiremark3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/RoadDirt/DI_TireMark_03.DI_TireMark_03'");
65 DecalNamesMap.Add(
"tarsnake1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake1.DI_tarsnake1'");
66 DecalNamesMap.Add(
"tarsnake2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake2.DI_tarsnake2'");
67 DecalNamesMap.Add(
"tarsnake3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake3.DI_tarsnake3'");
68 DecalNamesMap.Add(
"tarsnake4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake4.DI_tarsnake4'");
69 DecalNamesMap.Add(
"tarsnake5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake5.DI_tarsnake5'");
70 DecalNamesMap.Add(
"tarsnake6",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake6.DI_tarsnake6'");
71 DecalNamesMap.Add(
"tarsnake7",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake7.DI_tarsnake7'");
72 DecalNamesMap.Add(
"tarsnake8",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake8.DI_tarsnake8'");
73 DecalNamesMap.Add(
"tarsnake9",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake9.DI_tarsnake9'");
74 DecalNamesMap.Add(
"tarsnake10",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake10.DI_tarsnake10'");
75 DecalNamesMap.Add(
"tarsnake11",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/TarSnakes/DI_tarsnake11.DI_tarsnake11'");
78 DecalNamesMap.Add(
"cracksbig1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig1.DI_cracksBig1'");
79 DecalNamesMap.Add(
"cracksbig2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig2.DI_cracksBig2'");
80 DecalNamesMap.Add(
"cracksbig3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig3.DI_cracksBig3'");
81 DecalNamesMap.Add(
"cracksbig4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig4.DI_cracksBig4'");
82 DecalNamesMap.Add(
"cracksbig5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig5.DI_cracksBig5'");
83 DecalNamesMap.Add(
"cracksbig6",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig6.DI_cracksBig6'");
84 DecalNamesMap.Add(
"cracksbig7",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig7.DI_cracksBig7'");
85 DecalNamesMap.Add(
"cracksbig8",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_cracksBig8.DI_cracksBig8'");
88 DecalNamesMap.Add(
"crack1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack01.DI_RoadCrack01'");
89 DecalNamesMap.Add(
"crack2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack02.DI_RoadCrack02'");
90 DecalNamesMap.Add(
"crack3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack05.DI_RoadCrack05'");
91 DecalNamesMap.Add(
"crack4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack09.DI_RoadCrack09'");
92 DecalNamesMap.Add(
"crack5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack11.DI_RoadCrack11'");
93 DecalNamesMap.Add(
"crack6",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack13.DI_RoadCrack13'");
94 DecalNamesMap.Add(
"crack7",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack15.DI_RoadCrack15'");
95 DecalNamesMap.Add(
"crack8",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Cracks/DI_RoadCrack16.DI_RoadCrack16'");
98 DecalNamesMap.Add(
"manhole1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Manhole/DI_Manhole01.DI_Manhole01'");
99 DecalNamesMap.Add(
"manhole2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Manhole/DI_Manhole02.DI_Manhole02'");
100 DecalNamesMap.Add(
"manhole3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Manhole/DI_Manhole03.DI_Manhole03'");
103 DecalNamesMap.Add(
"mud1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/MudDecal/DI_Mud_1.DI_Mud_1'");
104 DecalNamesMap.Add(
"mud2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/MudDecal/DI_Mud_2.DI_Mud_2'");
105 DecalNamesMap.Add(
"mud3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/MudDecal/DI_Mud_3.DI_Mud_3'");
106 DecalNamesMap.Add(
"mud4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/MudDecal/DI_Mud_4.DI_Mud_4'");
107 DecalNamesMap.Add(
"mud5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/MudDecal/DI_Mud_5.DI_Mud_5'");
110 DecalNamesMap.Add(
"oilsplat1",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/OilSplats/DI_OilSplat1.DI_OilSplat1'");
111 DecalNamesMap.Add(
"oilsplat2",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/OilSplats/DI_OilSplat2.DI_OilSplat2'");
112 DecalNamesMap.Add(
"oilsplat3",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/OilSplats/DI_OilSplat3.DI_OilSplat3'");
113 DecalNamesMap.Add(
"oilsplat4",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/OilSplats/DI_OilSplat4.DI_OilSplat4'");
114 DecalNamesMap.Add(
"oilsplat5",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/OilSplats/DI_OilSplat5.DI_OilSplat5'");
117 DecalNamesMap.Add(
"gum",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/OilSplats/DI_Gum.DI_Gum'");
118 DecalNamesMap.Add(
"grate",
"MaterialInstanceConstant'/Game/Carla/Static/Decals/Road/Manhole/DI_Grate_01_v2.DI_Grate_01_v2'");
123#if WITH_EDITORONLY_DATA
126void ULoadAssetMaterialsCommandlet::ApplyRoadPainterMaterials(
const FString &LoadedMapName,
const FString &PackageName,
bool IsInTiles)
129 if (IsInTiles ==
true) {
135 FString MapName = LoadedMapName;
138 int32 idx = MapName.Find(
"_Tile_");
142 MapName = MapName.Mid(0, idx);
151 TArray<FString> FileList;
153 IFileManager::Get().FindFilesRecursive(FileList, *(FPaths::ProjectContentDir() +
"/" + PackageName +
"/Maps/" + MapName), *(FString(
"TilesInfo.txt")),
true,
false,
false);
157 if (FFileHelper::LoadFileToString(TxtFile, *FileList[0]) ==
true) {
161 TxtFile.ParseIntoArray(Out, TEXT(
","),
true);
170 UE_LOG(LogTemp, Warning, TEXT(
"Could not read TilesInfo.txt file"));
179 TArray<FString> StringArray = {};
180 LoadedMapName.ParseIntoArray(StringArray, TEXT(
"_"),
false);
182 int32 XIndex = FCString::Atoi(*StringArray[StringArray.Num() - 2]);
183 int32 YIndex = FCString::Atoi(*StringArray[StringArray.Num() - 1]);
184 FVector TilePosition;
188 TilePosition.Z = 0.0f;
203 if (ReadConfigFile ==
true) {
205 DecalsProperties = ReadDecalsConfigurationFile(PackageName);
206 ReadConfigFile =
false;
224 for (int32 i = 0; i < DecalsProperties.DecalMaterials.Num(); ++i) {
226 for (int32 j = 0; j < DecalsProperties.DecalNumToSpawn[i]; ++j) {
235 FVector FinalLocation(RoadLocation);
242 FRotator FinalRotation(XODRMap->ComputeTransform(Wp.get()).rotation);
251 FActorSpawnParameters SpawnParams;
252 SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
253 SpawnParams.bNoFail =
true;
254 ADecalActor* Decal =
World->SpawnActor<ADecalActor>(FinalLocation, FRotator(), SpawnParams);
255 Decal->SetDecalMaterial(DecalsProperties.DecalMaterials[i]);
258 float RandScale = FMath::RandRange(DecalsProperties.DecalMinScale, DecalsProperties.DecalMaxScale);
259 FVector FinalDecalScale;
260 FinalDecalScale.X = DecalsProperties.DecalScale.X + RandScale;
261 FinalDecalScale.Y = DecalsProperties.DecalScale.Y + RandScale;
262 FinalDecalScale.Z = 1.0f;
263 Decal->SetActorScale3D(FinalDecalScale);
266 float RandomYaw = FMath::RandRange(0.0f, DecalsProperties.DecalRandomYaw);
267 FinalRotation.Yaw += RandomYaw;
268 FinalRotation.Pitch = -90.0f;
269 Decal->SetActorRotation(FinalRotation);
270 Decal->SetActorLabel(
"RoadDecal",
true);
277 UEditorLoadingAndSavingUtils::SaveDirtyPackages(
true,
true);
282FDecalsProperties ULoadAssetMaterialsCommandlet::ReadDecalsConfigurationFile(
const FString &PackageName) {
285 FString JsonConfigFile;
287 TArray<FString> FileList;
288 IFileManager::Get().FindFilesRecursive(FileList, *(FPaths::ProjectContentDir() +
"/" + PackageName),
289 *(FString(
"roadpainter_decals.json")),
true,
false,
false);
292 if (FFileHelper::LoadFileToString(JsonConfigFile, *(IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*FileList[0]))))
294 TSharedPtr<FJsonObject> JsonParsed;
295 TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonConfigFile);
296 if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
299 auto DecalJsonArray = JsonParsed->GetArrayField(TEXT(
"decals"));
300 for (
auto &DecalJsonValue : DecalJsonArray)
302 const auto DecalJsonObject = DecalJsonValue->AsObject();
307 if (DecalJsonObject->HasField(Pair.Key) ==
true) {
308 DecalConfiguration.
DecalMaterials.Add(LoadObject<UMaterialInstanceConstant>(
nullptr, *Pair.Value));
309 DecalConfiguration.
DecalNumToSpawn.Add(DecalJsonObject->GetIntegerField(Pair.Key));
313 TSharedPtr<FJsonObject> VectorObject = DecalJsonObject->GetObjectField(TEXT(
"decal_scale"));
315 DecalScale.X = (float)VectorObject->GetNumberField(TEXT(
"x_axis"));
316 DecalScale.Y = (float)VectorObject->GetNumberField(TEXT(
"y_axis"));
317 DecalScale.Z = (float)VectorObject->GetNumberField(TEXT(
"z_axis"));
320 DecalConfiguration.
DecalMinScale = (float)DecalJsonObject->GetNumberField(TEXT(
"decal_min_scale"));
321 DecalConfiguration.
DecalMaxScale = (float)DecalJsonObject->GetNumberField(TEXT(
"decal_max_scale"));
322 DecalConfiguration.
DecalRandomYaw = (float)DecalJsonObject->GetNumberField(TEXT(
"decal_random_yaw"));
323 DecalConfiguration.
RandomOffset = (float)DecalJsonObject->GetNumberField(TEXT(
"random_offset"));
327 return DecalConfiguration;
333 TArray<FString> PackageList;
334 IFileManager::Get().FindFilesRecursive(PackageList, *(FPaths::ProjectContentDir()),
335 *(PackageName + TEXT(
".Package.json")),
true,
false,
false);
337 if (PackageList.Num() == 0)
339 UE_LOG(LogTemp, Error, TEXT(
"Package json file not found."));
343 return IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*PackageList[0]);
346void ULoadAssetMaterialsCommandlet::LoadAssetsMaterials(
const FString &PackageName,
const TArray<FMapData> &MapsPaths)
349 FAssetData AssetData;
350 MapObjectLibrary = UObjectLibrary::CreateLibrary(UWorld::StaticClass(),
false, GIsEditor);
351 const FString DefaultPath = TEXT(
"/Game/") + PackageName + TEXT(
"/Maps/");
353 for (
auto &&data : MapsPaths)
364 for (int32 i = 0; i < NumAssets; ++i) {
368 World = Cast<UWorld>(AssetData.GetAsset());
369 if (
World !=
nullptr) {
374 TArray<AActor*> FoundActors;
375 UGameplayStatics::GetAllActorsOfClass(
World, AStaticMeshActor::StaticClass(), FoundActors);
376 bool HasRoadMesh =
false;
377 for (int32 j = 0; j < FoundActors.Num() && HasRoadMesh ==
false; ++j) {
379 AStaticMeshActor *MeshActor = Cast<AStaticMeshActor>(FoundActors[j]);
380 if (MeshActor->GetName().Contains(
"Roads") || MeshActor->GetName().Contains(
"Road")){
386 if (HasRoadMesh ==
true) {
388 bool IsTiledMap =
World->GetName().Contains(
"_Tile_", ESearchCase::Type::CaseSensitive);
389 ApplyRoadPainterMaterials(
World->GetName(), PackageName, IsTiledMap);
393 UEditorLoadingAndSavingUtils::SaveDirtyPackages(
true,
true);
400FPackageParams ULoadAssetMaterialsCommandlet::ParseParams(
const FString &InParams)
const
402 TArray<FString> Tokens;
403 TArray<FString> Params;
404 TMap<FString, FString> ParamVals;
406 ParseCommandLine(*InParams, Tokens, Params);
411 FParse::Value(*InParams, TEXT(
"PackageName="), PackageParams.
Name);
413 return PackageParams;
416FAssetsPaths ULoadAssetMaterialsCommandlet::GetAssetsPathFromPackage(
const FString &PackageName)
const
423 FString MapsFileJsonContent;
424 if (FFileHelper::LoadFileToString(MapsFileJsonContent, *PackageJsonFilePath))
426 TSharedPtr<FJsonObject> JsonParsed;
427 TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(MapsFileJsonContent);
428 if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
431 auto MapsJsonArray = JsonParsed->GetArrayField(TEXT(
"maps"));
433 for (
auto &MapJsonValue : MapsJsonArray)
435 TSharedPtr<FJsonObject> MapJsonObject = MapJsonValue->AsObject();
438 MapData.
Name = MapJsonObject->GetStringField(TEXT(
"name"));
439 MapData.
Path = MapJsonObject->GetStringField(TEXT(
"path"));
442 AssetsPaths.
MapsPaths.Add(std::move(MapData));
446 auto PropJsonArray = JsonParsed->GetArrayField(TEXT(
"props"));
448 for (
auto &PropJsonValue : PropJsonArray)
450 TSharedPtr<FJsonObject> PropJsonObject = PropJsonValue->AsObject();
452 const FString PropAssetPath = PropJsonObject->GetStringField(TEXT(
"path"));
454 AssetsPaths.
PropsPaths.Add(std::move(PropAssetPath));
461int32 ULoadAssetMaterialsCommandlet::Main(
const FString &Params)
468 LoadAssetsMaterials(PackageParams.
Name, AssetsPaths.
MapsPaths);
471 UEditorLoadingAndSavingUtils::SaveDirtyPackages(
true,
true);
UE_LOG(LogCarla, Log, TEXT("UActorDispatcher::Destroying actor: '%s' %x"), *Id, Actor)
TSharedPtr< const FActorInfo > carla::rpc::ActorState UWorld * World
carla::geom::Location DecalLocation
float FirstTileWorldLocationX
float FirstTileWorldLocationY
TArray< FAssetData > AssetDatas
UObjectLibrary * MapObjectLibrary
TMap< FString, FString > DecalNamesMap
boost::optional< carla::road::Map > XODRMap
FString GetFirstPackagePath(const FString &PackageName) const
TSubclassOf< ARoadPainterWrapper > RoadPainterSubclass
FLargeMapTileData TileData
ULoadAssetMaterialsCommandlet()
static FString LoadXODR(const FString &MapName)
static boost::optional< road::Map > Load(const std::string &opendrive)
包含从 .Package.json 文件中读取的所有资产数据的结构
TArray< FMapData > MapsPaths
TArray< FString > PropsPaths
float DecalRandomYaw
The decal yaw to be applied randomly
float DecalMaxScale
Maximum scale to be applied to the decals
TArray< int32 > DecalNumToSpawn
How many decals (or material instances) of each, should be applied to the road
float RandomOffset
Random offset from one decal to another
TArray< UMaterialInstance * > DecalMaterials
The decals used on the road
float DecalMinScale
Min scale to be applied to the decals
FVector DecalScale
Scale of each decal on the road
FVector FixedDecalOffset
Min offset from one decal to another
包含从 .Package.json 文件中读取的地图数据的结构体
bool bUseCarlaMapMaterials
包含带有 Name 的 Package 和 bOnlyPrepareMaps 标志的结构体,用于 在不同阶段分离地图和道具的烹饪过程(地图将在 make import 命令期间导入,而道具将在 make...