diff --git a/Source/StevesUEHelpers/Private/StevesAssetHelpers.cpp b/Source/StevesUEHelpers/Private/StevesAssetHelpers.cpp new file mode 100644 index 0000000..d9ba280 --- /dev/null +++ b/Source/StevesUEHelpers/Private/StevesAssetHelpers.cpp @@ -0,0 +1,80 @@ +#include "StevesAssetHelpers.h" + +#include "StevesUEHelpers.h" +#include "Engine/ObjectLibrary.h" + +int UStevesAssetHelpers::FindBlueprintSoftPaths(const TArray& InPaths, + UObjectLibrary* ObjectLibrary, + TArray& 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 StrPaths; + for (auto& Dir : InPaths) + { + StrPaths.Add(Dir.Path); + } + return FindBlueprintSoftPaths(StrPaths, ObjectLibrary, OutSoftPaths); +} + +int UStevesAssetHelpers::FindBlueprintSoftPaths(const TArray& InPaths, + UObjectLibrary* ObjectLibrary, + TArray& OutSoftPaths) +{ + ObjectLibrary->LoadBlueprintAssetDataFromPaths(InPaths); + ObjectLibrary->LoadAssetsFromAssetData(); + // Now they're all loaded, add them + TArray FoundAssets; + ObjectLibrary->GetAssetDataList(FoundAssets); + int Count = 0; + for (auto& Asset : FoundAssets) + { + // Need to resolve BP generated class + const FString GeneratedClassTag = Asset.GetTagValueRef(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& InPaths, + UObjectLibrary* ObjectLibrary, + TArray& 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 StrPaths; + for (auto& Dir : InPaths) + { + StrPaths.Add(Dir.Path); + } + return FindBlueprintClasses(StrPaths, ObjectLibrary, OutClasses); +} + +int UStevesAssetHelpers::FindBlueprintClasses(const TArray& InPaths, + UObjectLibrary* ObjectLibrary, + TArray& OutClasses) +{ + TArray SoftPaths; + FindBlueprintSoftPaths(InPaths, ObjectLibrary, SoftPaths); + int Count = 0; + for (auto& SoftRef : SoftPaths) + { + if (UClass* TheClass = Cast(SoftRef.ResolveObject())) + { + OutClasses.Add(TheClass); + ++Count; + } + } + return Count; + +} diff --git a/Source/StevesUEHelpers/Public/StevesAssetHelpers.h b/Source/StevesUEHelpers/Public/StevesAssetHelpers.h new file mode 100644 index 0000000..40eadcf --- /dev/null +++ b/Source/StevesUEHelpers/Public/StevesAssetHelpers.h @@ -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& InPaths, UObjectLibrary* ObjectLibrary, TArray& 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& InPaths, UObjectLibrary* ObjectLibrary, TArray& 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& InPaths, UObjectLibrary* ObjectLibrary, TArray& 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& InPaths, UObjectLibrary* ObjectLibrary, TArray& OutClasses); + + +};