Let’s make our enemy go boom. Adding explosion animations to my Space Shooter
Exciting times in my 2D Space Shooter! Animating explosions! It’s one thing to do the code to wipe out the enemy or player, but to add a cool looking explosion is just going to make your game so much more immersive!
As always there are many ways to do this. That’s the most awesome thing about coding, you can come up with different ways of making things happen.
I’m going to be creating a prefab of the explosion and attach it to the enemy. When the laser (or player) collides with the enemy it’s going to trigger the explosion animation to play. But by all means feel free to play with this, it’s a great opportunity for you to do some research and try your hand at creating your own process.
Let’s start off by animating our explosion. Because we are going to be destroying our enemy it’s a good idea to hop into the look dev of our enemy. This will just give a nice close up of our enemy in our scene view. To do this, just double click on the Enemy prefab and you will see the enemy image is now in the scene.
Now we can create the animation. As you learned before, make sure the Animation window is open and docked next to our Game/Console window. To do this, Window, Animation, Animation. This will open the Animation window and have the little Create button there. Make sure your Enemy Prefab is selected and click on Create. Save your animation as Enemy_Destroyed_anim.
So now we have our animation playing for when the laser collides with our enemy. Great! Let’s see how this plays out…
Uhm… ok that’s not very good. The enemy is not only exploding as soon as they are instantiated, but they are exploding over and over again even after they are destroyed!
Some work to do here..
First thing, let’s take care of the fact that it is looping. Remember that Unity sets the animations to loop because really most of the time when you animate something it loops. To do this, inside the Project window click on the animations folder. Inside this you will see the Enemy and Enemy_Destroyed_anim. Click on the second one and you will see in the Inspector a check box for Loop Time. Uncheck this.
Now that will stop the looping problem but the enemy is still going to explode on start up. We need to fix that and can do so by using States inside of the animation controller. Don’t worry, it’s a lot easier than it sounds.
First, click on the Animations folder inside the Project window and then find the Enemy controller (see gif below, it is hilighted). Double click on this and it will open up the animator view. The animator view is going to allow us to manipulate the way the animation plays out. For example, you can see in the gif at the start when I double click it has the Entry and Enemy_Destroyed_anim. The issue here is the Entry is when the game starts and you can see the line to the Enemy_Destroyed. So the game starts and jumps directly to the orange box. The orange box signifies that it is the default state. So we need to have something break that transition from Entry — the default state. Right click in the window and click Create State — Empty and name it Empty. Now we can join the Entry to the Empty and it will fix the auto-exploding enemy.
So now if you were to save your scene and run it, the enemies would be safe and not explode. It’s now playing the empty scene and note the explosion.
So now we can connect the Empty to the Enemy_Destroyed_anim. But to do so we have to set a condition to the transition or it is just going to go Start — Empty — Explosion. It is just delaying the explosion, not allowing us to use a laser collision condition.
So now, we need to figure out a way to make the transition between Empty — Enemy_Destgroyed_anim have a condition. So it won’t make the jump until something happens.
The way to do this is creating something called Parameters. Parameters use 4 different kinds of logic — Float, Int, Bool and Trigger. Each works in it’s own way to allow us to create logic through code. So in our case, we want to work with Trigger. We want something to “Trigger” the transition between Empty and the explosion animation.
So in the top left of Unity you will see a Parameters tab. Click on that and click the drop down and Trigger. Now rename this to OnEnemyDeath. Now click on the line (the transition) between Empty and Enemy_Destroyed_anim and in the Inspector you will see a Setting bar. Below it Conditions. Click the + and it will automatically populate it with y our new trigger OnEnemyDeath.
Now we still need the code to make this function properly, but we can test it out in live action. Play the game and click on the little circle in the Parameters. You will see the enemy explode. Basically what you are doing by clicking on the circle is activating that parameter. Now we need to figure out how to do this through code.
Ok, so we need to decide where we are going to run this code. What is happening? What are we trying to do? Well, we want to add an explosion to the enemy when it’s destroyed. So it would make sense to place this code inside of the enemy script. This way we will have easy access to the Animator that the Trigger we need to access is attached to as well as the code that happens when the enemy is hit by the laser or player.
So inside of the Enemy script, we need to create a handle to the Animator. A variable that we can use to manipulate the Animator.
We now need to assign the component we want to get (The Animator) to the variable we created.
Now we have our Animator and have complete access to the OnEnemyDeath parameter we created. We just need to set it.. SetTrigger function will work nicely here. So this line needs to go in the collision code we already have. Becareful where you place this though, if you put it after the Destroy object code it won’t work because the object will be destroyed BEFORE the animation and not work. So place it just before like so:
So basically we are just taking the variable _anim that holds the Animator and using the . to step inside of the Animator allowing us to SetTrigger. We put the OnEnemyDeath in “”. Make sure you spell this exactly how you did in the Unity Editor.
Could this work!? Let’s check…
Well. That’s annoying. Why isn’t that working?
I’m showing you this to give you a bit insight into debugging your code. So in this case it took me a bit because I thought the trigger wasn’t working. I wasn’t getting access to the OnEnemyDeath. But after a few minutes it dawned on me, we are telling Unity to play the animation but we are telling it to do so RIGHT after we play the animation. So we aren’t giving it time. If you go back into Unity and run the animation you will see that it takes around 2.3 seconds to run the full length of it. So we need to delay the Destroy function! Let’s add this:
All I’m doing here is adding 2.8 to the Destroy function. What this is going to do now is make it wait 2.8 seconds BEFORE destroying it. Let’s see how this works.
Well, almost. It’s a bit too long of a delay there. Let’s play with that 2.8f number and set it to 2.4f.
Also, I’m going to slow the enemy ship down when it’s hit. I don’t like how it’s flying at the same speed when hit by the player. I just add a _speed = 1; after the animation but before the destroy.
Let’s have a look now.
Ok, that’s better. Not perfect but better. I’m not sure if I like how the enemy slows down so much. But I’ll have a play with this and have my testers tell me what they think. Remember, TEST TEST TEST!
Tomorrow we will work on the player and add some cool effects when he is hit. Maybe a smoking wing or something. Don’t miss it!