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: