While our game may be running without any issues in the editor or even in…
Actor Spawning and GetDefaultObject
Sometimes we need to spawn Actors in-game which are based on C++ classes. Moreover, we’re going to see what the function GetDefaultObject<T> does and why you should know about it! Let’s get started!
Actor Spawning
For this post, we will create two Actors. One will contain some dummy logic just for the sake of this post (let’s call this actor UsefulActor), and the other one will spawn the UsefulActor after a specified period of time. The first step is to add a new C++ class (which is based on the Actor class), named UsefulActor and type in the following logic in its header file:
Switch to your editor, and create a blueprint based on this class named BP_UsefulActor. Make sure to add a static mesh in your Blueprint in order to be able tell when your Actor has spawned.
After we’re done with the UsefulActor, add another C++ class named ActorSpawner (which inherits from the Actor class as well). Inside its header file, include the UsefulActor.h and type in the following code:
The TSubclassOf<AUsefulActor> means that this property can accept any object of type AUsefulActor. Since we made a blueprint based on this class, we can pass the Blueprint as a paremeter in this property.
Make sure to include the “UsefulActor.h” before the ActorSpawner.generated.h. Otherwise you project won’t compile.
Switch to the ActorSpawner.cpp file and add the following functionality:
Compile your code and create a Blueprint based on the ActorSpawner class we just created. Then, open up the Blueprint you just created and in the UsefulActorBP property, add the BP_UsefulActor and not the UsefulActor class like the following image suggests.
When you’re done with that, place the ActorSpawner Blueprint somewhere in your level and click on play/simulate button. The BP_UsefulActor should spawn after “Time To Spawn” seconds you provided in your Blueprint.
Epic’s API provides some useful overloads of the SpawnActor function which can be found here.
The reason we chose the Blueprint class instead of the C++ class in the UsefulActorBP property, is because we want to spawn the Blueprint and not the C++ class. Even though our Blueprint is based on the C++ class we stored specific values in the Blueprint and not inside the class, like the static mesh we’ve added above. This is a likely scenario even in real projects. Most times, you will create an Actor based on a C++ class which has some custom properties. Then, you switch to your editor and fill out these properties. So when you want to spawn the specific Actor with all the properties you’ve placed through the Editor you will choose the Blueprint instead of the C++ class.
GetDefaultObject<T>
In the previous example, when we spawned a new Actor we stored a reference to a pointer. Let’s say that we forgot to store that reference and later on we would like to access the DoSomething function which resides in the class AUsefulActor. You might be thinking this is quite straight forward. Since we have the UsefulActorBP stored we will just access the DoSomething function from there. However, when you type the following line of code:
UsefulActorBP->DoSomething();
your code won’t compile. And the error that you get is the following one:
Hm, that’s strange! Even though the TSubclassOf accepts any derived class of AUsefulActor we can’t use any C++ functions. This is where the GetDefaultObject<T> comes in handy. This function, allows us to get the parent class of the subclass we’ve used above (which is where the c++ functions “reside”). So, the following line will compile and execute just fine:
UsefulActorBP->GetDefaultObject<AUsefulActor>()->DoSomething();
An alternative way of having access to the c++ functions of AUsefulActor would be to cast the BP to it’s parent. However, casting is usually an “expensive” operation in terms of performance.
I don’t know how long ago this was written, but THANK YOU THANK YOU THANK YOU
I must have spent 12 hours over the past few days trying to decipher poorly-written forum posts and out-of-date examples about spawning, you really are a god amongst mortals.
I agree with Jon.
This forum has been nothing , but informative and helpful. Please keep it up!
I’ve been struggling with instantiating a blueprint for the past day. You well written article sorted out all my problems and more. Thank you for such a clear and concise tutorial.
Where did we define AUsefulActor? Is it just an instance of UsefulActor?
The AUsefulActor class is the class we created in the beginning of the tutorial.
-Orfeas
My details pane does not have actor spawning option where you have set the useful actor bp
Make sure that you have exposed your TSubClass in Blueprints and that you have compiled your code. If things go wrong you may need to restart the engine.
-Orfeas
This seems to only work if you have a “spawner” type actor – is there a way to modify this so that I can spawn a blueprint class at a given transform without having another actor present? I tried giving the C++ class a TSubclassOF itself but that still requires an instance of the class in order to spawn the blueprint class.
You can use this technique in a custom class setup as Singleton in your project settings, this avoid the necessity to have a spawner class + gives you the recommended way to access global soft references 🙂