In the Infinite Runner Engine, in most cases, the player doesn’t move across the level like it would in a “classic” game, as the level is infinite. Instead, the world comes at it. This is usually done using spawners. Spawners are entities that you’ll usually want to place outside of the camera’s view, and that will periodically spawn objects from their Object Pool. You’ll want to check that page first if you don’t know what they are. There are different kinds of spawners included in the engine, that will allow you to spawn things based on time spent, distance between spawned objects, or even link objects via certain points. You can also of course extend the spawner base class to suit your specific needs. If you want to have a quick look at the different spawners and their possibilities, you can check out the Sandbox demo scene, which contains a lot of different, barebones spawners. Just activate them in the hierarchy view and press play.
Spawners are really amazing tools, that can be used in a lot of different ways. In the picture above, a simple DistanceSpawner has been added to an object with an AutoRotate component. You can have moving spawners, rotating ones, spawners that follow your character, etc. The possibilities are infinite!
The Spawner base class
The Spawner class is meant to be extended. Don’t add it to any of your objects directly. It handles all common features of all spawners :
- getting objects from the pool
- size modification of the object and ratio preservation
- rotation of the object
- object spawn (obviously)
The Spawner class has also got a few public properties you can set from other classes, such as Spawning (if true, will spawn objects, otherwise not), OnlySpawnWhileGameInProgress, to prevent a spawner from spawning enemies during your level’s introduction for example, and InitialDelay, which will prevent the spawner from spawning during the X first seconds of your game.
A TimedSpawner is a spawner that will periodically spawn objects based on time spent since the last spawn. From its inspector you can define the minimum and maximum time that should elapse between two spawns, and it’ll randomize a value within this range for every spawn. Of course if you want an object to spawn after the same time everytime, just put the same value in the two fields.
You can also specify two vectors for min and max position. Same as the time, the TimedSpawner will randomize a position within these bounds every time, and add that to the spawner’s position to determine the object’s initial position.
A DistanceSpawner is a spawner that will spawn objects based on the distance between it and the object, or the distance between the last spawned object and the next one. You can define that via the GapOrigin property in its inspector. Then, also in the inspector, you can set the gap (min and max values) between spawns. You can add clamp values, to prevent objects to spawn too far away from the spawner. You can also have the Spawner force the rotation of the spawned object based on its own rotation. That way, your spawner can rotate (even at runtime) to spawn objects in any direction you want.
A LinkedSpawner is a special kind of Spawner that will allow you to spawn LinkedSpawnedObjects and position them accordingly. LinkedSpawnedObjects are objects that have an In and Out link points, and the next spawned object will attach its In point to the previously spawned object’s Out point.
Creating such objects is quite simple. Just take any sprite or model based gameobject, and add a LinkedSpawnedObject to it. From its inspector you’ll be able to position its in and out points. You’ll even see them precisely on the scene view via handy little gizmos.
Classes you can add to your spawned objects
MovingObject: In most situations, you’ll want to spawn objects that move. Maybe they have their own AI, but if you just want them to move towards the player, you’ll need to add the MovingObject component to them. It’s a simple component that will, at Update(), move the object in the specified direction, at the specified speed+acceleration, factored by the current level’s speed (set in the LevelManager).
OutOfBoundsRecycle: Now that your objects move, you’ll probably want them to stop existing at some point, so they can get recycled and not just clog your memory. There are two ways you can do that. In their PoolableObject’s inspector you can define their lifetime. But maybe you don’t know for how long the object will be on screen and interactable, so that doesn’t cover all situations. Fortunately, there’s the OutOfBoundsRecycle component for that. It’ll automatically disable your object if it goes beyond the Level bounds (defined in the LevelManager). You can even specify a distance beyond these bounds it should wait to have traveled before getting destroyed.