Download

Spawn Blueprint Class with input parameters C++

Hi, I am fairly new to UE4 development so apologies if I am missing something obvious.

I am trying to convert a system from blueprints to C++. In an attempt to convert the SpawnActor node, I found that I am unable to provide input parameters as in the image below where ‘Index’ is a custom input.

SpawnActorBPNode

In other places, to resolve this issue, I have used BeginDeferredActorSpawnFromClass, used an initialise function to provide parameters, then call FinishSpawningActor. This has worked where I am calling a C++ class.

In this case however, the actor I want to spawn is a blueprint class which is a child based on a C++ class. I am unable to implement BeginDeferredActorSpawnFromClass for this, and therefore am not sure how to pass my parameter to this.

For extra context, in the project there can be multiple characters spawned in the world. I want to pass the index of the character in order to set the material colour of each individual character using the nodes shown below.

image

I am able to achieve this by spawning the BP character using:

Character = GetWorld()->SpawnActor(...)
Character->Index = Index

And then using EventTick instead of EventBeginPlay but feel this is a bad solution. I would appreciate if someone could advise how to initialise the spawned actor with the required parameter.

Thanks in advance.

If I understand your problem correctly, you can’t. Not easily.

The way that you’ve resolved your other problems with BeginDeferredActorSpawnFromClass is what you want to be doing. However when spawning an instance of a blueprint class there’s no way for C++ to easily interact with the properties or functions declared in blueprint.

For example, let’s say you had an AFoo blueprint derived directly from AActor. Native code would only be able to interact with it in any way that is available from the AActor API. If you’ve added a new function to AFoo, native will never be able to call it. Ditto for any properties added to the blueprint.

It’s generally recommended that if you want C++ to be interacting with your type, you should declare a type in C++ that your blueprint derive from. Then the C++ type can have all the properties/functions/events that native needs to interface with and blueprint can add things that it doesn’t need to care about.

Caveat: I specifically said there wasn’t an easy way to do these things because there are ways to interact with those properties/functions from native. The built in serialization is proof enough of that. But it involves using the reflection information and treating your instances in a kind of weird way that I don’t recommend unless you really have to. It’s an advanced option that requires very good reasons and usually making an intermediate type that defines the native interface is way, way, easier and understandable.

I see, thanks for your response.

I think I didn’t explain very well, but I managed to find a solution which I probably should have found much sooner.

My previous implementation was:

UObject *SpawnActor = StaticLoadObject(UObject::StaticClass(), NULL, TEXT("/Game/Blueprints/BP_LMPCharacter.BP_LMPCharacter"));
	
ALMPCharacter *Character = GetWorld()->SpawnActor<ALMPCharacter>(
	Cast<UBlueprint>(SpawnActor)->GeneratedClass,
	InputReceiver->GetTransform());
	
Character->PlayerIndex = CurrentPlayerIndex;

Which did not update the Playerindex value prior to the creation of the actor and hence the change of PlayerIndex would only be detected by using the EventTick function.

While I tried to implement BeginDeferredActorSpawnFromClass I somehow missed SpawnActorDeferred which works exactly as I wanted, allowing me to initialise the PlayerIndex variable before spawning the actor. The fully functional code is now:

UObject *SpawnActor = StaticLoadObject(UObject::StaticClass(), NULL, TEXT("/Game/Blueprints/BP_LMPCharacter.BP_LMPCharacter"));
	
ALMPCharacter *Character = GetWorld()->SpawnActorDeferred<ALMPCharacter>(
	Cast<UBlueprint>(SpawnActor)->GeneratedClass,
	InputReceiver->GetTransform());
	
Character->PlayerIndex = CurrentPlayerIndex;

UGameplayStatics::FinishSpawningActor(Character, InputReceiver->GetTransform());