Location Based Spawning
A common requirement of a game is to place entities into the environment. This is usually known as ‘spawning’. There are many ways to implement spawning since there are many different requirements. For example, spawning players into a game has different needs to spawning Space Invaders on a screen. In my Xevious port I need to be able to spawn various different types of enemies depending upon how far the player has traveled. One method would be to define the enemies in waves, typically using Unity’s Scriptable Objects. You can see an example of my implementation in a Tower Defence game.
For a space shooter like Xevious, it is less about waves per se, more about exactly what part of the screen the player can see.
So just spawning a little tank at some random position on the screen is not going to be good enough, it needs to be more precise. I need to know exactly what the player can see, and the exact location the enemy should start from.
Spawn locations via GameObjects
One of the goals of this projects is to make it level-designer friendly. I do not want the spawn timings and positions to be numbers and (x,y) coordinate based locations, it should visually plot onto the map.
My current solution is drop empty game objects with their icons set. In the previous picture you can see red circles denoting airborne enemies and green dot for land-based. As you can see the land based one is directly on the visuals for a road. With this method it is very easy for a designer to correctly position the enemies.
When to Spawn?
Since I am not using a time-based spawning method, I need to detect when the Spawn Locations are shown to the player. For this job I have created a MapTrigger script;
It is currently using an Update message method. I have some ideas how to optimize that but that is not the job for now. When the scripts detects it is in the bounds of the camera is raises a OnInView event and a corresponding OnOutOfView event when it is out of view. Since this event is static it allows my SpawnManager to subscribe and react accordingly. Currently that mechanism is a little clunky. The raised event contains the object raising it, and the SpawnManager has a simple name-to-pool mapping.
Again, please forgive early code :S The Spawn Manager matches the name of the object raising the event and places it at the exact location of the MapTrigger. It then uses a nasty brute force examination of the spawned objects capabilities to decide how to start the objects behaviour. Currently that is either going to be either;
- ITimedTarget — attack the player’s ship but runaway after a timed interval
- IWaypoints —move between way-points
Notice that the way-points are also visually placed on the map, eventually they will have nice icons, but again not yet.
Road Map from here
The code is ‘good enough’ to deliver a basic spawning mechanism. That frees me to look at the next stage which is firing and collisions. However, the current SpawnManager is far from finished. I suspect I will have tooling to place the correct type of MapTrigger on the screen to include a concrete relationship to the type of enemy. Together with a new EnemyRuleManager I shall be able to decouple that nasty code. But if you look back at the opening title gif, you can see where the enemy is spawning from and how they have different behaviours and hopefully you will agree that it is pretty easy for a level designer to build.