Trying To Load Multiple Actors From Content Browser C++

I am trying to get a lot of actors from a specific folder in my content browser. For some reason I can access the names and locations but I cannot spawn the objects.\

What I have tried:

Using blueprints:

I tried to use blueprints to load an asset data structure full of objects. I then tried to use that data to spawn in actor classes of the objects I found but it would not work. I could only access the name, file location, and the class.

But the assets’ classes would only appear as a blueprint class and could never be casted as Actor which is their original class.

I tried to use “Spawn Actor from Object” and Spawn Actor from Class" but it would not produce a valid actor and therefore not spawn anything.

I quickly decided what needed to be done is coding through C++ instead of through blueprints since I have prior knowledge in spawning 1 actor from the content browser.
C++:

How I previously learn how to load an asset in was like so:

bool AObjectSpawnManager::GetNewActorByName(FString newActorName)
{
	bool foundActor = false;
	// file location should be:
	// Blueprint'/Game/ObjectsToBeAdded/Blueprints/
	// specifically Blueprint'/Game/ObjectsToBeAdded/Blueprints/BP.BP'
	//  or it could be Blueprint'/Game/ObjectsToBeAdded/Blueprints/PleaseWork.PleaseWork'
	FString tempFileLoc = fileLocation + newActorName + "." + newActorName;

	// this is the hard coded way for the object but it still does not find it
	//tempFileLoc = "Blueprint'/Game/ObjectsToBeAdded/Blueprints/PleaseWork.PleaseWork'";

	UObject* newActor = Cast<UObject>(StaticLoadObject(UBlueprint::StaticClass(), NULL, *tempFileLoc, NULL, LOAD_None, NULL));
	UBlueprint* GeneratedBP = Cast<UBlueprint>(newActor);

	if (newActor != nullptr) {
		UE_LOG(LogTemp, Display, TEXT("FoundObj %s at %s"), *newActorName, *tempFileLoc);

		actorBPToSpawn = GeneratedBP->GeneratedClass;

		foundActor = true;
	}
	else {
		UE_LOG(LogTemp, Error, TEXT("Could not find %s in the location: %s"), *newActorName, *tempFileLoc);
	}
	return foundActor;
}

// a simple that spawns the blueprint found
void AObjectSpawnManager::SpawnNewActor()
{

	if (actorBPToSpawn != NULL)
	{
		FActorSpawnParameters spawnParams;
		spawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;

		GetWorld()->SpawnActor<AActor>(actorBPToSpawn, GetActorTransform(), spawnParams);
		UE_LOG(LogTemp, Display, TEXT("spawning"));
	}
	else {
		UE_LOG(LogTemp, Error, TEXT("actorBPToSpawn is null"));
	}

}

the problem with this method is that I would need the objects names before hand. I would like to be able to just grab whatever is in the folder and manipulate it during runtime.


After some research I was told using UObjectLibrary would help me in this endeavor, but I have kind of hit the wall in trying to make this work.

In my constructor I have

AObjectSpawnManager::AObjectSpawnManager()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	objectList = UObjectLibrary::CreateLibrary(AActor::StaticClass(), true, true);
	objectList->AddToRoot();

	if (fileLocation.Len() > 0) {
		UE_LOG(LogTemp, Error, TEXT("yes file"));
		UE_LOG(LogTemp, Error, TEXT("FileLoc %s"), *fileLocation);
	}
	else {
		// here is the default locaiton for the objects
		fileLocation = "/Game/ObjectsToBeAdded/Blueprints/";

		UE_LOG(LogTemp, Error, TEXT("no file"));
		UE_LOG(LogTemp, Error, TEXT("FileLoc %s"), *fileLocation);
	}

	objectList->LoadBlueprintsFromPath(fileLocation);
	UE_LOG(LogTemp, Error, TEXT("is list MADE"));
	int amount = objectList->GetObjectCount();
	UE_LOG(LogTemp, Error, TEXT("FoundObjAmount %i"), amount);
	


}

so I end up finding 6 objects… even though there are 3. but that doe not matter to me at the moment I just want the ability to grab them and put them into the game.

So after filling the list I go into trying to make a TArray of Actors so I can access it for testing purposes.

TArray<AActor*> AObjectSpawnManager::GetObjects() {
	TArray<AActor*> objects;

	if (objectList == nullptr) {
		objectList = UObjectLibrary::CreateLibrary(AActor::StaticClass(), true, true);
		objectList->LoadBlueprintsFromPath(fileLocation);
		UE_LOG(LogTemp, Error, TEXT("amount found %i"), objectList->GetObjectCount());
	}


	objectList->GetObjects(objects);
	UE_LOG(LogTemp, Error, TEXT("class %i "), objects.Num());
	/*
	for (int i = 0; i < objectList->GetObjectCount(); i++) {

		UE_LOG(LogTemp, Error, TEXT("class %i "), i);
		UE_LOG(LogTemp, Error, TEXT("class %s "), *objects[i]->StaticClass()->GetName());
		//objects.Add(Cast<AActor>(objectList[i].StaticClass()));
	}*/

	return objects;
}

This leads to an array of 6 but none of them are valid actors still…

Another problem I have run into is that objectList tends to become a nullptr after construction and throughout function calls. Hense teh constant check to see if the objectList is null or not.

I am not sure what I am doing wrong here and would like some help in pointing me in the right direction.

Resources I have been using:

Did not read the full thing but see my answer here (the second part mostly) for transforming asset references (from AssetRegistry search results) into usable classes, this can be done in BP.

C++ can work too and should be similar.
Either way, you should avoid loading the Blueprint type objects as they are editor-only content, stripped out when packaging the project. So loading the Blueprint to access its GeneratedClass will not work in packaged. As mentioned in my answer above you can load directly the generated class using the _C postfix.

I am posting more to thank Chatouille for leading me in the right direction. I was able to get it all working as intended because of him. I also wanted to use this to learn more about WHY it is done this way and to answer any questions I have for this. I will provide the solution I came to at the end

I am currently using Unreal 5.0.3 I cannot seem to find Get Blueprint Assets nor can I find Make TopLevelAssetPath

Is this a deprecated method from previous versions or were these added in newer versions?

The best way I could find to get the AssetData is by using GetAssetsByPath and using a LiteralName for the package path. I can still break the AssetData but it would seem that I cannot use the Append of the string and put it into ToSoftObjectReference because it requires a Soft Object Path Structure.

I did end up finding the solution is to start from LoadAssetBlocking then you turn off Context Sensitive checkmark in the solution and search MakeSoftObjectPath. This allowed me to convert the string to the Soft Object Path structure. Then I was able to append the Package Name and Asset Name gotten from the AssetData like so:
PkName.AssetName_C

So a question I have is why the _C? is this to signify it as a class object or does it mean something else?

THE SOLUTION Unreal 5.0.1