Added UStevesAssetHelpers and useful finding blueprints functions

This commit is contained in:
Steve Streeting 2024-03-19 16:32:39 +00:00
parent 92d7000dbe
commit 3ca0e0dff6
2 changed files with 134 additions and 0 deletions

View File

@ -0,0 +1,80 @@
#include "StevesAssetHelpers.h"
#include "StevesUEHelpers.h"
#include "Engine/ObjectLibrary.h"
int UStevesAssetHelpers::FindBlueprintSoftPaths(const TArray<FDirectoryPath>& InPaths,
UObjectLibrary* ObjectLibrary,
TArray<FSoftObjectPath>& OutSoftPaths)
{
// LoadBlueprintAssetDataFromPaths requires FString array, LoadBlueprintAssetDataFromPath just makes one array per call so no better
// I like using FDirectoryPath for settings though since it enables browsing
TArray<FString> StrPaths;
for (auto& Dir : InPaths)
{
StrPaths.Add(Dir.Path);
}
return FindBlueprintSoftPaths(StrPaths, ObjectLibrary, OutSoftPaths);
}
int UStevesAssetHelpers::FindBlueprintSoftPaths(const TArray<FString>& InPaths,
UObjectLibrary* ObjectLibrary,
TArray<FSoftObjectPath>& OutSoftPaths)
{
ObjectLibrary->LoadBlueprintAssetDataFromPaths(InPaths);
ObjectLibrary->LoadAssetsFromAssetData();
// Now they're all loaded, add them
TArray<FAssetData> FoundAssets;
ObjectLibrary->GetAssetDataList(FoundAssets);
int Count = 0;
for (auto& Asset : FoundAssets)
{
// Need to resolve BP generated class
const FString GeneratedClassTag = Asset.GetTagValueRef<FString>(FBlueprintTags::GeneratedClassPath);
if (GeneratedClassTag.IsEmpty())
{
UE_LOG(LogStevesUEHelpers, Warning, TEXT("Unable to find GeneratedClass value for asset %s"), *Asset.GetObjectPathString());
continue;
}
FSoftObjectPath StringRef;
StringRef.SetPath(FPackageName::ExportTextPathToObjectPath(GeneratedClassTag));
OutSoftPaths.Add(StringRef);
++Count;
}
// Don't use OutSoftPaths.Num() in case it wasn't empty to start with
return Count;
}
int UStevesAssetHelpers::FindBlueprintClasses(const TArray<FDirectoryPath>& InPaths,
UObjectLibrary* ObjectLibrary,
TArray<UClass*>& OutClasses)
{
// LoadBlueprintAssetDataFromPaths requires FString array, LoadBlueprintAssetDataFromPath just makes one array per call so no better
// I like using FDirectoryPath for settings though since it enables browsing
TArray<FString> StrPaths;
for (auto& Dir : InPaths)
{
StrPaths.Add(Dir.Path);
}
return FindBlueprintClasses(StrPaths, ObjectLibrary, OutClasses);
}
int UStevesAssetHelpers::FindBlueprintClasses(const TArray<FString>& InPaths,
UObjectLibrary* ObjectLibrary,
TArray<UClass*>& OutClasses)
{
TArray<FSoftObjectPath> SoftPaths;
FindBlueprintSoftPaths(InPaths, ObjectLibrary, SoftPaths);
int Count = 0;
for (auto& SoftRef : SoftPaths)
{
if (UClass* TheClass = Cast<UClass>(SoftRef.ResolveObject()))
{
OutClasses.Add(TheClass);
++Count;
}
}
return Count;
}

View File

@ -0,0 +1,54 @@
#pragma once
#include "CoreMinimal.h"
#include "StevesAssetHelpers.generated.h"
class UObjectLibrary;
/// Class to help out with asset related tasks, mostly C++ only but defined as a BPL in case that's useful later
UCLASS()
class STEVESUEHELPERS_API UStevesAssetHelpers : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
/**
* Find the soft object paths of blueprints matching an object library definition, in a given set of paths.
* @param InPaths The asset paths to search. Must be game-directory form e.g. /Game/Data
* @param ObjectLibrary The object library which defines the (super)class which you're looking for. You should
* have created this similar to: `UObjectLibrary::CreateLibrary(UYourAssetClass::StaticClass(), true, GIsEditor && !IsRunningCommandlet());`
* @param OutSoftPaths Output array of soft object paths to the blueprints found. You can resolve these using their ResolveObject() function.
* @returns The number of blueprint assets found
*/
static int FindBlueprintSoftPaths(const TArray<FDirectoryPath>& InPaths, UObjectLibrary* ObjectLibrary, TArray<FSoftObjectPath>& OutSoftPaths);
/**
* Find the soft object paths of blueprints matching an object library definition, in a given set of paths.
* @param InPaths The asset paths to search. Must be game-directory form e.g. /Game/Data
* @param ObjectLibrary The object library which defines the (super)class which you're looking for. You should
* have created this similar to: `UObjectLibrary::CreateLibrary(UYourAssetClass::StaticClass(), true, GIsEditor && !IsRunningCommandlet());`
* @param OutSoftPaths Output array of soft object paths to the blueprints found. You can resolve these using their ResolveObject() function.
* @returns The number of blueprint assets found
*/
static int FindBlueprintSoftPaths(const TArray<FString>& InPaths, UObjectLibrary* ObjectLibrary, TArray<FSoftObjectPath>& OutSoftPaths);
/**
* Find a list of loaded classes for blueprints matching an object library definition, in a given set of paths.
* @param InPaths The asset paths to search. Must be game-directory form e.g. /Game/Data
* @param ObjectLibrary The object library which defines the (super)class which you're looking for. You should
* have created this similar to: `UObjectLibrary::CreateLibrary(UYourAssetClass::StaticClass(), true, GIsEditor && !IsRunningCommandlet());`
* @param OutClasses Output array of loaded UClass objects representing the blueprints found.
* @returns The number of blueprint assets found
*/
static int FindBlueprintClasses(const TArray<FDirectoryPath>& InPaths, UObjectLibrary* ObjectLibrary, TArray<UClass*>& OutClasses);
/**
* Find the soft object paths of blueprints matching an object library definition, in a given set of paths.
* @param InPaths The asset paths to search. Must be game-directory form e.g. /Game/Data
* @param ObjectLibrary The object library which defines the (super)class which you're looking for. You should
* have created this similar to: `UObjectLibrary::CreateLibrary(UYourAssetClass::StaticClass(), true, GIsEditor && !IsRunningCommandlet());`
* @param OutClasses Output array of loaded UClass objects representing the blueprints found.
* @returns The number of blueprint assets found
*/
static int FindBlueprintClasses(const TArray<FString>& InPaths, UObjectLibrary* ObjectLibrary, TArray<UClass*>& OutClasses);
};