LifePlay-Revival/Source/LifePlay/LPAssetRegistryHelpers.cpp
edujiro5972 56dfcfc3d2 LifePlay UE 5.8 : état de développement au 2026-10-20
Tickets : PUB-20261020-T1

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 17:35:10 +02:00

89 lines
3.6 KiB
C++

// Portage UE 5.5 (2026.9 beta) - voir LPAssetRegistryHelpers.h
#include "LPAssetRegistryHelpers.h"
#include "LifePlay.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "AssetRegistry/IAssetRegistry.h"
#include "Modules/ModuleManager.h"
FAssetData ULPAssetRegistryHelpers::GetAssetByObjectPath(const FName ObjectPath, bool bIncludeOnlyOnDiskAssets)
{
const FAssetRegistryModule& AssetRegistryModule =
FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
// 5.1+ : la surcharge prenant un FName est depreciee. La broche Blueprint reste un
// FName (les noeuds rebranches par la commandlet en dependent), seule la conversion
// vers FSoftObjectPath est faite ici.
const FSoftObjectPath Path(ObjectPath.ToString());
const FAssetData Result = AssetRegistryModule.Get().GetAssetByObjectPath(Path, bIncludeOnlyOnDiskAssets);
// Lot STM1 (STM1-SPEC-01, T1) : GI.MoveCity resout ici StreetMapName et StaticMeshName de la ville. Chaque
// resolution d'un chemin de ville est tracee (sans le dedoublonnage ci-dessous) ; un chemin qui finit par '/'
// est la valeur par defaut de la structure City, rendue par GetCityByName quand le nom de ville est introuvable.
const FString PathString = ObjectPath.ToString();
if (PathString.StartsWith(TEXT("/Game/Heavy/StreetMap"), ESearchCase::IgnoreCase))
{
const TCHAR* Label = PathString.EndsWith(TEXT("/"))
? TEXT(" (chemin par defaut de City : ville non trouvee)")
: (PathString.Contains(TEXT("000Dummy"), ESearchCase::IgnoreCase) ? TEXT(" (ville factice)") : TEXT(""));
UE_LOG(LogLPCity, Log, TEXT("[LPCity] RESOLUTION '%s' -> %s%s"),
*PathString, Result.IsValid() ? TEXT("OK") : TEXT("ECHEC"), Label);
}
// Lot L5 (ERR-027) : tout chemin non resolu est signale une fois, avec la forme exacte
// recue et celle interpretee par FSoftObjectPath. Les maillages charges par chemin
// (corps, vetements, coiffures) passent tous par ici ; un echec produit un personnage
// sans maillage, sans aucune autre trace.
if (!Result.IsValid())
{
// Appele depuis les Blueprints, donc sur le thread de jeu.
static TSet<FName> ReportedFailures;
bool bAlreadyReported = false;
ReportedFailures.Add(ObjectPath, &bAlreadyReported);
if (!bAlreadyReported)
{
UE_LOG(LogLifePlay, Warning, TEXT("GetAssetByObjectPath ECHEC | recu '%s' | interprete '%s' (valide=%d) | OnlyOnDisk=%d"),
*ObjectPath.ToString(), *Path.ToString(), Path.IsValid() ? 1 : 0, bIncludeOnlyOnDiskAssets ? 1 : 0);
}
}
else
{
UE_LOG(LogLifePlay, Verbose, TEXT("GetAssetByObjectPath OK | '%s'"), *ObjectPath.ToString());
}
return Result;
}
bool ULPAssetRegistryHelpers::GetAssetsByClassName(FName ClassName, TArray<FAssetData>& OutAssetData, bool bSearchSubClasses)
{
OutAssetData.Reset();
if (ClassName.IsNone())
{
return false;
}
// TryFindTypeSlow resout un nom court ("SkeletalMesh") vers la classe reelle, quel que
// soit son module : /Script/Engine.SkeletalMesh comme /Script/StreetMapRuntime.StreetMap.
const UClass* ResolvedClass = UClass::TryFindTypeSlow<UClass>(ClassName.ToString());
if (!ResolvedClass)
{
UE_LOG(LogTemp, Warning, TEXT("LPAssetRegistryHelpers : classe '%s' introuvable."), *ClassName.ToString());
return false;
}
const FAssetRegistryModule& AssetRegistryModule =
FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
return AssetRegistryModule.Get().GetAssetsByClass(
FTopLevelAssetPath(ResolvedClass), OutAssetData, bSearchSubClasses);
}
FName ULPAssetRegistryHelpers::GetAssetObjectPath(const FAssetData& AssetData)
{
if (!AssetData.IsValid())
{
return NAME_None;
}
return FName(*AssetData.GetSoftObjectPath().ToString());
}