2025-04-01 22:31:27 -04:00
|
|
|
|
|
|
|
|
#include "AssetLookup.h"
|
|
|
|
|
#include "AssetRegistry/IAssetRegistry.h"
|
|
|
|
|
#include "AssetRegistry/AssetData.h"
|
|
|
|
|
#include "AssetRegistry/AssetRegistryState.h"
|
|
|
|
|
#include "LuprexGameModeBase.h"
|
2025-04-07 16:48:27 -04:00
|
|
|
#include "Components/Widget.h"
|
|
|
|
|
#include "WidgetBlueprint.h"
|
|
|
|
|
#include "Blueprint/UserWidget.h"
|
2025-11-14 02:41:44 -05:00
|
|
|
#include "Animation/AnimSequence.h"
|
2025-06-18 16:25:46 -04:00
|
|
|
#include "Engine/StaticMesh.h"
|
2025-04-01 22:31:27 -04:00
|
|
|
|
|
|
|
|
|
2025-11-14 02:41:44 -05:00
|
|
|
const ElxValidOrNotValid NotValid = ElxValidOrNotValid::NotValid;
|
|
|
|
|
const ElxValidOrNotValid Valid = ElxValidOrNotValid::Valid;
|
|
|
|
|
|
|
|
|
|
void UlxAssetLookup::RebuildIndex()
|
|
|
|
|
{
|
|
|
|
|
IAssetRegistry::GetChecked().WaitForCompletion();
|
|
|
|
|
AssetPaths.Empty();
|
|
|
|
|
AddAssets(TEXT("/Game/StaticMeshes"), UStaticMesh::StaticClass(), TEXT("SM_"));
|
|
|
|
|
AddAssets(TEXT("/Game/AnimSequences"), UAnimSequence::StaticClass(), TEXT("SEQ_"));
|
|
|
|
|
AddAssets(TEXT("/Game/Tangibles"), UBlueprint::StaticClass(), TEXT("TAN_"));
|
|
|
|
|
AddAssets(TEXT("/Game/Widgets"), UWidgetBlueprint::StaticClass(), TEXT("WB_"));
|
2025-04-01 22:31:27 -04:00
|
|
|
}
|
|
|
|
|
|
2025-11-14 04:42:04 -05:00
|
|
|
void UlxAssetLookup::AddAssets(const TCHAR *Path, UClass *Class, const TCHAR *NamePrefix)
|
2025-04-01 22:31:27 -04:00
|
|
|
{
|
2025-04-07 16:48:27 -04:00
|
|
|
TArray<FAssetData> FoundData;
|
2025-11-14 02:41:44 -05:00
|
|
|
TMap<FName, FString> Result;
|
2025-04-07 16:48:27 -04:00
|
|
|
FARFilter AssetFilter;
|
2025-11-14 02:41:44 -05:00
|
|
|
AssetFilter.PackagePaths.Add(FName(Path));
|
|
|
|
|
AssetFilter.ClassPaths.Add(Class->GetClassPathName());
|
2025-04-07 16:48:27 -04:00
|
|
|
AssetFilter.bIncludeOnlyOnDiskAssets = true;
|
|
|
|
|
AssetFilter.bRecursivePaths = true;
|
|
|
|
|
IAssetRegistry::GetChecked().GetAssets(AssetFilter, FoundData);
|
2025-11-14 02:41:44 -05:00
|
|
|
FString FSNamePrefix(NamePrefix);
|
2025-04-07 16:48:27 -04:00
|
|
|
|
|
|
|
|
for (const FAssetData &Data : FoundData)
|
|
|
|
|
{
|
2025-11-14 02:41:44 -05:00
|
|
|
FString AssetName = Data.AssetName.ToString();
|
|
|
|
|
if (AssetName.StartsWith(FSNamePrefix))
|
|
|
|
|
{
|
|
|
|
|
FName ShortName(AssetName.RightChop(FSNamePrefix.Len()));
|
|
|
|
|
AssetPaths.Add(MakeTuple(Class->GetName(), ShortName), Data.GetObjectPathString());
|
|
|
|
|
}
|
2025-04-07 16:48:27 -04:00
|
|
|
}
|
2025-04-01 22:31:27 -04:00
|
|
|
|
2025-11-14 02:41:44 -05:00
|
|
|
UE_LOG(LogLuprexIntegration, Display, TEXT("Found %d assets of type %s in %s"),
|
|
|
|
|
FoundData.Num(), *Class->GetName(), Path);
|
2025-04-01 22:31:27 -04:00
|
|
|
}
|
|
|
|
|
|
2025-11-14 04:42:04 -05:00
|
|
|
UObject *UlxAssetLookup::LoadAsset(const UObject *Context, UClass *Class, UClass *ChildOf, const FString &Name, bool ErrorIfNotFound)
|
2025-04-07 16:48:27 -04:00
|
|
|
{
|
2025-11-14 02:41:44 -05:00
|
|
|
const UlxAssetLookup *Lookup = ALuprexGameModeBase::FromContext(Context)->GetAssetLookup();
|
|
|
|
|
const FString *Path = Lookup->AssetPaths.Find(MakeTuple(Class->GetName(), FName(Name)));
|
|
|
|
|
if (Path == nullptr)
|
|
|
|
|
{
|
2025-11-14 04:42:04 -05:00
|
|
|
if (ErrorIfNotFound)
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(LogLuprexIntegration, Error, TEXT("Loading %s %s: asset not found"), *Class->GetName(), *Name);
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UObject *Result;
|
|
|
|
|
if (ChildOf == nullptr)
|
|
|
|
|
{
|
|
|
|
|
Result = StaticLoadObject(Class, nullptr, **Path);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Result = StaticLoadObject(UClass::StaticClass(), nullptr, *((*Path) + FString(TEXT("_C"))));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Result == nullptr)
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(LogLuprexIntegration, Error, TEXT("Loading %s %s: unknown load failure"), *Class->GetName(), *Name);
|
|
|
|
|
return nullptr;
|
2025-11-14 02:41:44 -05:00
|
|
|
}
|
2025-11-14 04:42:04 -05:00
|
|
|
|
|
|
|
|
if (ChildOf != nullptr)
|
|
|
|
|
{
|
|
|
|
|
UClass *ResClass = (UClass *)Result;
|
|
|
|
|
if (!ResClass->IsChildOf(ChildOf))
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(LogLuprexIntegration, Error, TEXT("Loading %s %s: blueprint not a child of %s"), *Class->GetName(), *Name, *ChildOf->GetName());
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Result;
|
2025-04-07 16:48:27 -04:00
|
|
|
}
|
|
|
|
|
|
2025-11-14 02:41:44 -05:00
|
|
|
ElxValidOrNotValid UlxAssetLookup::LoadStaticMeshAsset(
|
|
|
|
|
UStaticMesh *&Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
|
2025-04-08 16:31:16 -04:00
|
|
|
{
|
2025-11-14 04:42:04 -05:00
|
|
|
Result = (UStaticMesh *)LoadAsset(Context, UStaticMesh::StaticClass(), nullptr, Name, ErrorIfNotFound);
|
|
|
|
|
return Result ? Valid : NotValid;
|
2025-04-08 16:31:16 -04:00
|
|
|
}
|
|
|
|
|
|
2025-11-14 02:41:44 -05:00
|
|
|
ElxValidOrNotValid UlxAssetLookup::LoadAnimSequenceAsset(
|
|
|
|
|
UAnimSequence *&Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
|
2025-04-01 22:31:27 -04:00
|
|
|
{
|
2025-11-14 04:42:04 -05:00
|
|
|
Result = (UAnimSequence *)LoadAsset(Context, UAnimSequence::StaticClass(), nullptr, Name, ErrorIfNotFound);
|
|
|
|
|
return Result ? Valid : NotValid;
|
2025-04-01 22:31:27 -04:00
|
|
|
}
|
|
|
|
|
|
2025-11-14 02:41:44 -05:00
|
|
|
ElxValidOrNotValid UlxAssetLookup::LoadTangibleBlueprintAsset(
|
|
|
|
|
TSubclassOf<AActor> &Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
|
|
|
|
|
{
|
2025-11-14 04:42:04 -05:00
|
|
|
Result = (UClass*)LoadAsset(Context, UBlueprint::StaticClass(), AActor::StaticClass(), Name, ErrorIfNotFound);
|
|
|
|
|
if (Result == nullptr) return NotValid;
|
2025-04-01 22:31:27 -04:00
|
|
|
UFunction *aqchanged = Result->FindFunctionByName(FName(TEXT("Animation Queue Changed")));
|
|
|
|
|
if ((aqchanged == nullptr)||(aqchanged->ParmsSize != 0))
|
|
|
|
|
{
|
2025-11-14 04:42:04 -05:00
|
|
|
UE_LOG(LogLuprexIntegration, Error, TEXT("Loading Blueprint %s: Tangible does not have 'Animation Queue Changed' function"), *Name);
|
2025-11-14 02:41:44 -05:00
|
|
|
Result = nullptr; return NotValid;
|
2025-04-07 16:48:27 -04:00
|
|
|
}
|
2025-11-14 02:41:44 -05:00
|
|
|
return Valid;
|
2025-04-07 16:48:27 -04:00
|
|
|
}
|
|
|
|
|
|
2025-11-14 02:41:44 -05:00
|
|
|
ElxValidOrNotValid UlxAssetLookup::LoadUserWidgetAsset(
|
|
|
|
|
TSubclassOf<UUserWidget> &Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
|
|
|
|
|
{
|
2025-11-14 04:42:04 -05:00
|
|
|
Result = (UClass *)LoadAsset(Context, UWidgetBlueprint::StaticClass(), UUserWidget::StaticClass(), Name, ErrorIfNotFound);
|
|
|
|
|
return Result ? Valid : NotValid;
|
2025-04-07 16:48:27 -04:00
|
|
|
}
|
|
|
|
|
|
2025-11-14 02:41:44 -05:00
|
|
|
ElxValidOrNotValid UlxAssetLookup::LoadLuaWidgetAsset(
|
|
|
|
|
TSubclassOf<UlxLuaWidget> &Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
|
|
|
|
|
{
|
2025-11-14 04:42:04 -05:00
|
|
|
Result = (UClass *)LoadAsset(Context, UWidgetBlueprint::StaticClass(), UlxLuaWidget::StaticClass(), Name, ErrorIfNotFound);
|
|
|
|
|
return Result ? Valid : NotValid;
|
2025-04-01 22:31:27 -04:00
|
|
|
}
|