Dynamically Spawn Blueprint Actor using C++ in a packaged game

Hi everyone,

I know there is at least one question with similar title but the difference is, I do not want to load the class in my constructor. I want to be able to spawn a blueprint actor as and when required. So far, I have tried a few methods, such as

UObject* tempObject			= StaticLoadObject( UObject::StaticClass(), nullptr, path, NULL, LOAD_None);

and

const IAssetRegistry& Registry = FModuleManager::LoadModuleChecked<FAssetRegistryModule>( "AssetRegistry" ).Get();
TArray<FAssetData> TemplateList;
Registry.GetAssetsByClass( UBlueprint::StaticClass()->GetFName(), TemplateList );

Spawning in editor works, but in a packaged game the required blueprint is not loaded. I have also added the following to DefaultEditor.ini.

 [EditoronlyBP]
 bDontLoadBlueprintOutsideEditor=false

Anyone has any idea how to get the blueprint loaded in a package game?

You restarted your editor after that change right?

Are you sure you’re looking up the BP class by its true class name vs blueprint name? it should end with _c

Link

Is there any reason you don’t want to use a reference to the class in the header and set that in blueprint, then spawn it elsewhere?:

UPROPERTY(EditAnywhere)
TSubclassOf<AMyClass> MyClass;

I do have an old function which loaded blueprints at runtime, and I think they did work in a shipping build of the game:

template <typename ObjClass>
static FORCEINLINE ObjClass* LoadBlueprintFromPath(const FName& Path, const FName& BlueprintName)
{
	if (Path == NAME_None) return NULL;
	FString cName = BlueprintName.ToString().Append(FString("_C"));
	TArray<UObject*> tempArray;
	if (EngineUtils::FindOrLoadAssetsByPath(*Path.ToString(), tempArray, EngineUtils::ATL_Class))
	{
		for (int i = 0; i < tempArray.Num(); ++i)
		{
			UObject* temp = tempArray[i];
			if (temp == NULL || (!Cast<ObjClass>(temp)) || (temp->GetName().Compare(cName) != 0))
			{
				continue;
			}

			return Cast<ObjClass>(temp);
		}
	}

	return NULL;
}

TSubclassOf<class AMyClass> MyClassBP_Class = LoadBlueprintFromPath<UClass>("/Game/Blueprints/Class", "Class");
1 Like

For StaticLoadObject(), I am using blueprint path in editor and it works. Changing to path with “_C” appended behind will not return a valid result. As for FAssetData, it successfully showed me the names of all blueprints for both editor mode and packaged game, but FAssetData::GetAsset() was uable to return the object because both FindObject and LoadObject failed to return anything.

The game I am doing has a variety of blueprint actors that can be spawned and attached to a character and all of them have a chance to be spawned, depending on what the player choses. So in my point of view, loading them dynamically should help reduce memory usage (I might be wrong on this). I’ll give your function a try and see if i can get it solved. Thanks :wink:

Hey Dune,

Thanks for the function! It is working perfectly now!

Hi there, I have a very similar issue when attempting to spawn blueprint actors at runtime in a packaged game. I’ve been trying to get your LoadBlueprintFromPath function working, but the TSubclassOf<> always appears to be null. I also made sure to set bDontLoadBlueprintOutsideEditor=false.

My goal is to read a blueprint from a .pak file and then spawn it as an actor. The blueprint will inherit from a C++ class. However, for now just to make things more simple, I am instead trying to spawn a blueprint from the Content folder.

Any help would be greatly appreciated!

My code below fails to spawn the actor.

TSubclassOf<ADinosaur> MyClassBP_Class = LoadBlueprintFromPath<UClass>("/Game/", "BP_Raptor");

ADinosaur* Dinosaur = GetWorld()->SpawnActor<ADinosaur>(MyClassBP_Class, FVector::ZeroVector, FRotator::ZeroRotator);

Never mind I got an answer to my question here:
https://www.reddit.com/r/unrealengine/comments/bjnwfp/spawning_blueprint_actors_at_runtime_in_a/