header:
UFUNCTION(BlueprintCallable, Category = "Sweet|Utilities")
static TArray<UObject*> DynamicLoadContentFromPath(FString PathFromContentFolder = "Audio/Music", UClass* AssetClass = nullptr, bool LoadFromSubfolders = false);
source:
TArray<UObject*> USweetFunctionLibrary::DynamicLoadContentFromPath(FString PathFromContentFolder /*= "Audio/Music"*/, UClass* AssetClass, bool LoadFromSubfolders)
{
TArray<UObject*> Array;
FString RootFolderFullPath = FPaths::ConvertRelativePathToFull(FPaths::GameDir()) + "Content/" + PathFromContentFolder + "/";
Print("RootFolderPath = " + RootFolderFullPath);
//FPaths::NormalizeDirectoryName(RootFolderFullPath);
//Print("Normalized RootFolderPath = " + RootFolderFullPath);
IFileManager& FileManager = IFileManager::Get();
TArray<FString> Files;
FString Ext;
if (LoadFromSubfolders)
{
if (!Ext.Contains(TEXT("*")))
{
if (Ext == "")
{
Ext = "*.*";
}
else
{
Ext = (Ext.Left(1) == ".") ? "*" + Ext : "*." + Ext;
}
}
FileManager.FindFilesRecursive(Files, *RootFolderFullPath, *Ext, true, false);
}
else
{
if (!Ext.Contains(TEXT("*")))
{
if (Ext == "")
{
Ext = "*.*";
}
else
{
Ext = (Ext.Left(1) == ".") ? "*" + Ext : "*." + Ext;
}
}
FileManager.FindFiles(Files, *(RootFolderFullPath + Ext), true, false);
}
for (int32 i = 0; i < Files.Num(); i++)
{
FString Path;
if (LoadFromSubfolders)
{
int32 LastForwardSlash = Files*.Find("/", ESearchCase::IgnoreCase, ESearchDir::FromEnd);
FString File = Files*.RightChop(LastForwardSlash + 1);
FString Folder = Files*.RightChop(Files*.Find(PathFromContentFolder, ESearchCase::CaseSensitive, ESearchDir::FromEnd) + PathFromContentFolder.Len());
Folder = Folder.LeftChop(File.Len() + 1);
File = File.Left(File.Find(".", ESearchCase::IgnoreCase, ESearchDir::FromEnd));
Path = AssetClass->GetFName().ToString() + "'/Game/" + PathFromContentFolder + Folder + "/" + File + "." + File + "'";
}
else
{
Path = AssetClass->GetFName().ToString() + "'/Game/" + PathFromContentFolder + "/" + Files*.LeftChop(7) + "." + Files*.LeftChop(7) + "'";
}
UObject* LoadedObj = StaticLoadObject(AssetClass, NULL, *Path);
Array.Add(LoadedObj);
}
for (int32 i = 0; i < Array.Num(); i++)
{
if (Array.Num() > 0 && Array* != nullptr)
{
Print(Array*->GetFName().ToString());
}
else
{
Print("Array is empty");
}
}
return Array;
}
Sort of a hacky job borrowing some of Rama’s code and working it into a way that works for me.
“Path from content folder” is exactly what it sounds like. The the folder structure starting AFTER “Content.” So if your textures are in “GameFolder/Content/Textures/SpecialTextures” then you’ll just write “Textures/SpecialTextures” here.
Specify the asset class you want to find and load. This filters out unwanted objects. In this example, I’m looking for Soundwaves. You can also specify whether or not you want to search subfolders.
You can only return one type from C++, so you’ll have to cast each of the UObjects that come back when placing them into your array.
This can run anytime - during the game at runtime, or before the game in the construction script or as part of a blutility. It all depends on when you want it to be loaded. You can also load them at runtime and copy the filled array from the inspector then paste it into the array variable.