In this article I’ll show you how we can keep a specific number of actors in the game world, and “replenish them” should they be removed. Imagine a game in which you pick flowers, and over time said flowers automatically re-grow but never exceed 10. Or a game in which the player battles against 5 other guys, and as soon as one is killed, another one is spawned. This works well in conjunction with my previous simple AI Controller article.
What we need in principle is:
- a class handling the continuos spawning
- a spawnable actor
- a physical object from which to spawn actors
Creating the Spawner Class
I’ll setup a new Actor class for my Spawner object. I’ll call it Enemy Spawner perhaps. In its viewport I’ll add a single Box Collision object with default size and values and name this Spawn Volume. This object is invisible in our game world, but we’ll use its size later and spawn red Unreal Guys from it that will all come towards me. It’ll be fun.
In the event graph I’ll setup a node that will spawn one of my Enemy Characters, on a random point in 3D space along the above Spawn Volume. The whole Spawner actor will sit above my game world, and when an Actor is spawned, it’ll fall right down at a random location.
To make this happen, I’ll use a Spawn AI from Class node. I’ll hook up its location input to a Random Point in Bounding Box node. This will literally do the boring maths to figure out a point in 3D space for us. Super neat! This node needs an origin and a Box Extent, so I’ll grab a reference to my Spawn Volume from the viewport and get both with Get World Location and Get Scaled Box Extent. The last node will give us the correct coordinates even if we scale up the whole object in our scene, unlike its sister node Get Unscaled Box Extent.
We need to call this Spawn AI From Class node, so I’ll setup a a custom even called Spawn Enemy for this. I’ll make sure only a certain number of objects will be spawned, or do nothing if we already have enough. Here’s what it looks like:
The clever bit is happening in the first node, Get All Actors Of Class. I’ll return a reference to every existing item of an Actor Class, and in my case I’m checking for Enemy Characters. We get the size of the array with a length node and test if this number is smaller than my maximum defined number of allowable objects in the scene. I’ve promoted this to a public variable so I can easily change this from the level details panel. If true (i.e. less than max enemies in my scene), it’ll go and spawn another enemy. The True pin connects to the node above.
Calling the Spawn Event
I’ll have my Game Mode handle the actual spawning. All I need is a reference to the Enemy Spawner so I’ll be able to call the Spawn Enemy event on it. I’d like to do this in regular intervals so I’ll set up a timer for that. Here’s what it looks like:
The first part grabs a reference to the only Enemy Spawner object in my scene. It’s a clever way of doing this without having to instantiate or otherwise grab it, using the “first item in array” principle.
The actual spawn timer is created with the last node, Set Timer by Function Name. All I need is a reference to the Enemy Spawner object, and a time interval in seconds. A whole number would do (like 2 for 2 per second), but an even cleverer way of doing it is by dividing 1 by said number and promoting it to a public variable for easier access. Mine is called Enemies per second, and whatever this number is set to will spawn x amount of enemies per second. For continuous execution, the timer is set to loop.
Adding the Spawner to the Scene
Let’s drag in the Enemy Spawner into our scene and make sure it sits above the level somewhere. Every spawned enemy will just drop down from that height, like we’ve seen so many times in video games. Scale it along the X/Y axis by finding the little connected line between X and Y and make it as big as you need it to be. Make sure the spawned objects have somewhere to land on.
And that’s all there’s to it! If you set the max amount of enemies to something like 50 and wait a bit, you’ll be surrounded by lots of people who have fallen from the sky.