#include "AssetLookup.h" #include "AssetRegistry/IAssetRegistry.h" #include "AssetRegistry/AssetData.h" #include "AssetRegistry/AssetRegistryState.h" #include "LuprexGameModeBase.h" #include "Components/Widget.h" #include "WidgetBlueprint.h" #include "Blueprint/UserWidget.h" void UlxAssetLookup::RebuildIndex() { CachedTangibles.Empty(); CachedStaticMeshes.Empty(); IAssetRegistry::GetChecked().WaitForCompletion(); ScanTangibles(); ScanStaticMeshes(); ScanWidgets(); } void UlxAssetLookup::ScanTangibles() { TArray FoundData; FARFilter AssetFilter; AssetFilter.PackagePaths.Add(FName(TEXT("/Game/Tangibles"))); AssetFilter.ClassPaths.Add(UBlueprint::StaticClass()->GetClassPathName()); AssetFilter.bIncludeOnlyOnDiskAssets = true; AssetFilter.bRecursivePaths = true; IAssetRegistry::GetChecked().GetAssets(AssetFilter, FoundData); UE_LOG(LogLuprexIntegration, Display, TEXT("Found %d assets in /Game/Tangibles"), FoundData.Num()); for (const FAssetData &Data : FoundData) { FString Path = Data.GetObjectPathString() + TEXT("_C"); CachedTangibles.Add(Data.AssetName, Path); } } void UlxAssetLookup::ScanStaticMeshes() { TArray FoundData; FARFilter AssetFilter; AssetFilter.PackagePaths.Add(FName(TEXT("/Game/StaticMeshes"))); AssetFilter.ClassPaths.Add(UStaticMesh::StaticClass()->GetClassPathName()); AssetFilter.bIncludeOnlyOnDiskAssets = true; AssetFilter.bRecursivePaths = true; IAssetRegistry::GetChecked().GetAssets(AssetFilter, FoundData); UE_LOG(LogLuprexIntegration, Display, TEXT("Found %d assets in /Game/StaticMeshes"), FoundData.Num()); for (const FAssetData &Data : FoundData) { FString Path = Data.GetObjectPathString(); CachedStaticMeshes.Add(Data.AssetName, Path); } } void UlxAssetLookup::ScanWidgets() { TArray FoundData; FARFilter AssetFilter; AssetFilter.PackagePaths.Add(FName(TEXT("/Game/Widgets"))); AssetFilter.ClassPaths.Add(UWidgetBlueprint::StaticClass()->GetClassPathName()); AssetFilter.bIncludeOnlyOnDiskAssets = true; AssetFilter.bRecursivePaths = true; IAssetRegistry::GetChecked().GetAssets(AssetFilter, FoundData); UE_LOG(LogLuprexIntegration, Display, TEXT("Found %d assets in /Game/Widgets"), FoundData.Num()); for (const FAssetData &Data : FoundData) { FString Path = Data.GetObjectPathString() + TEXT("_C"); CachedWidgets.Add(Data.AssetName, Path); } } FString UlxAssetLookup::TangibleLoadPath(const FName &AssetName) const { const FString *Result = CachedTangibles.Find(AssetName); if (Result == nullptr) return TEXT(""); return *Result; } FString UlxAssetLookup::StaticMeshLoadPath(const FName &AssetName) const { const FString *Result = CachedStaticMeshes.Find(AssetName); if (Result == nullptr) return TEXT(""); return *Result; } FString UlxAssetLookup::WidgetLoadPath(const FName &AssetName) const { const FString *Result = CachedWidgets.Find(AssetName); if (Result == nullptr) return TEXT(""); return *Result; } UStaticMesh *UlxAssetLookup::GetStaticMeshByName(const UObject *Context, const FString &Name, bool ErrorIfNotFound, bool ErrorIfInvalid) { ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(Context); FString Path = mode->GetAssetLookup()->StaticMeshLoadPath(FName(FString("SM_") + Name)); if (Path.IsEmpty()) { if (ErrorIfNotFound) UE_LOG(LogLuprexIntegration, Error, TEXT("Static mesh not on search path: %s"), *Name); return nullptr; } UStaticMesh *Result = LoadObject(nullptr, *Path); if (Result == nullptr) { if (ErrorIfInvalid) UE_LOG(LogLuprexIntegration, Error, TEXT("Cannot load static mesh: %s"), *Path); return nullptr; } return Result; } TSubclassOf UlxAssetLookup::GetTangibleClassByName(const UObject *Context, const FString &Name, bool ErrorIfNotFound, bool ErrorIfInvalid) { ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(Context); FString Path = mode->GetAssetLookup()->TangibleLoadPath(FName(FString("TAN_") + Name)); if (Path.IsEmpty()) { if (ErrorIfNotFound) UE_LOG(LogLuprexIntegration, Error, TEXT("Tangible not on search path: %s"), *Name); return nullptr; } UClass *Result = LoadObject(nullptr, *Path); if (Result == nullptr) { if (ErrorIfInvalid) UE_LOG(LogLuprexIntegration, Error, TEXT("Cannot load tangible class: %s"), *Path); return nullptr; } if (!Result->IsChildOf(AActor::StaticClass())) { if (ErrorIfInvalid) UE_LOG(LogLuprexIntegration, Error, TEXT("Tangible class is not an actor: %s"), *Path); return nullptr; } UFunction *aqchanged = Result->FindFunctionByName(FName(TEXT("Animation Queue Changed"))); if ((aqchanged == nullptr)||(aqchanged->ParmsSize != 0)) { if (ErrorIfInvalid) UE_LOG(LogLuprexIntegration, Error, TEXT("Tangible does not have 'Animation Queue Changed' function: %s"), *Path); return nullptr; } return Result; } TSubclassOf UlxAssetLookup::GetWidgetByName(const UObject *Context, const FString &Name, bool ErrorIfNotFound, bool ErrorIfInvalid) { ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(Context); FString Path = mode->GetAssetLookup()->WidgetLoadPath(FName(FString("WB_") + Name)); if (Path.IsEmpty()) { if (ErrorIfNotFound) UE_LOG(LogLuprexIntegration, Error, TEXT("Widget not on search path: %s"), *Name); return nullptr; } UClass *Result = LoadObject(nullptr, *Path); if (Result == nullptr) { if (ErrorIfInvalid) UE_LOG(LogLuprexIntegration, Error, TEXT("Cannot load widget blueprint: %s"), *Path); return nullptr; } if (!Result->IsChildOf(UUserWidget::StaticClass())) { if (ErrorIfInvalid) UE_LOG(LogLuprexIntegration, Error, TEXT("Blueprint is not a Widget Blueprint: %s"), *Path); return nullptr; } return Result; } TSubclassOf UlxAssetLookup::GetLookAtWidgetByName(const UObject *Context, const FString &Name, bool ErrorIfNotFound, bool ErrorIfInvalid) { ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(Context); FString Path = mode->GetAssetLookup()->WidgetLoadPath(FName(FString("WB_") + Name)); if (Path.IsEmpty()) { if (ErrorIfNotFound) UE_LOG(LogLuprexIntegration, Error, TEXT("Widget not on search path: %s"), *Name); return nullptr; } UClass *Result = LoadObject(nullptr, *Path); if (Result == nullptr) { if (ErrorIfInvalid) UE_LOG(LogLuprexIntegration, Error, TEXT("Cannot load widget blueprint: %s"), *Path); return nullptr; } if (!Result->IsChildOf(UlxLookAtWidget::StaticClass())) { if (ErrorIfInvalid) UE_LOG(LogLuprexIntegration, Error, TEXT("Blueprint is not a Luprex Look-At Widget: %s"), *Path); return nullptr; } return Result; }