In the previous part, I discussed how we could start creating a track for our infinite runner, and also how to make our avatar move.
Right now, we have an avatar that runs on the tracks but eventually falls because we only have a limited number of track sections. This time, we will make it so that new track sections are created as they are needed, so the avatar doesn’t fall off the track.
There are different ways to add sections, like adding a new section automatically after X seconds. However, this poses another issue: if you constantly create sections, you’ll reach a point where you have a lot of them, and that may impact your game performance a lot.
In other words, at some point your system will run out of memory. Since it’s a simple game, and they are simple objects, it would take a lot to run out of memory but that doesn’t mean it may not happen if someone is playing your game on a lower end system (for example, my game is primarily aimed at the PlayStation Vita, so I have to deal with a lot of hardware limitations). This means you also need to figure out a way to get rid of the track sections you are no longer using (the ones left behind the avatar).
Luckily, we can deal with both problems in one go by creating a routine that “detects” when an old section must be deleted a new one created. To do this, I can add a box object as a child to my avatar, activate the “Is Trigger” checkbox in the Box Collider component, increase its size in X and Y (width and height) and move it a little more than 100 to the back (because our track elements are 100 units in length). The idea is this: when a track section touches this trigger, it will fire an event that will delete that track section, and create a new one at the end.
To make things easier and more manageable, create a new tag, and assign that tag to your track section prefab like in the image below:
Now what you need to do is select the object that had your FSM component that created the tracks (as seen in the previous tutorial). This one already creates 3 track sections (or as many as you had decided in the previous part). First, create a new event to that state machine called “add,” and then right click on your “counter” state and select “add transition” and select the “add” transition. Then you create two new states (called “next_position 2” and “state 1” in the image below), and configure them as shown below.
The idea of the full state machine (including the parts we had already created) is: first, it will create 3 track sections, one after another with an offset of 100 units in Z axis (so the first is created at Z = 0, the next one at Z = 100 and the last one at Z = 200), and when it has created those three, it will move on to the “next_position 2” where it sets the position for the upcoming track section that will be created eventually (Z = 300 in this case). Then, the “addsection” event will be triggered externally “by something” (this is where the trigger of our avatar will come into play), and, when it’s fired, the state machine will launch the “state 1” event where it creates a new track element at the designated position (Z = 300) and then wait X amount of seconds and go back to “next_position 2” and wait for the instruction to add a new section.
Now, go back to the trigger created as a child of our avatar, add an FSM component to it, and create the following state machine:
This is what happens: when the track object touches the trigger it will fire the “destroy” event (please note that I’ve set the “Collide Tag” parameter to match the track object’s tag, as assigned above), and the colliding object is stored as a variable hitObj (store hit object). The next state will destroy the “hitObj” object (in this case, the track object that touched the trigger) and then it uses the “Send Event By Name” action to fire the “addsection” event in our track created (state machine explained above).
Now, all you have to do is press play, and, if everything goes the way I think, none of this will work…
The reason is very simple: for the trigger to detect the collision, your track object prefab must have a rigid body component. I decided to leave this out until now because, in many situations, you are trying to get triggers to work and then you realize you are missing the rigid body component.
So, now you can add a rigid body component to your track section prefab, but make sure you check the “is kinematic” checkbox, or else your track section will fall down. The “is kinematic” parameter turns off any forces applied to the element (this can be used for different purposes, but here it’s used simply so that tracks are not affected by gravity).
Now, you can hit play, and everything should work the way it’s supposed to.