Feature Highlight: Creating Visual Effects and Animation Triggers in Unity
Visual effects are an awesome way to engage your user and enhance the perceived quality of your game. Let’s dive into some options for our Space Shooter game.
We have a few events in this game that would be enhanced by visual effects. The first is when we destroy enemies — there should definitely be an explosion. Second, when our player gets damaged we should have a visual representation to reflect the level of damage / lives remaining.
Let’s walk through the enemy explosion implementation — when our laser hits our enemy prefab we want it to trigger an explosion at the spot of our enemy. Here is where some smoke and mirrors comes in — there is no way to tell Unity to simply make our object explode, but rather we can swap the enemy ship sprite with an animated sprite that shows our explosion effect.
To begin, we navigate to and open our Enemy prefab, then the Animation window, and create a new animation for EnemyExplosion. We select record, highlight all frames in the animation sequence, and drag them into the Animation window. Now we have a few things to adjust to make this work properly. We do not want this animation to trigger until our enemies collide with our laser, but right now we have explosions happening by themselves as soon as the enemy is instantiated.
This is because our animator controller is telling the system to run the explosion animation as soon as we enter the game. To fix this we need to adjust the default state in our animator controller away from the explosion and set up a new trigger to fire the animation.
First we create a new empty state and set it to default. This stops our animations from running instantly. Next we create a transition from this empty state to our destroyed animation, and create a new parameter that will determine when we transition between the states. Animator parameters allow you to control the states of your animations using game logic controlled by your code such as a trigger, bool, int, or float.
We create a new parameter of type Trigger called OnEnemyDeath and assign this to the transition from empty to our explosion animation. Be sure to also uncheck “Has exit time” so our transition will be instant.
Now we need to trigger this behavior through code at the moment our laser or player collides with the Enemy — we do this within our OnTriggerEnter2D method within the enemy script.
We create a reference to the animator on the Enemy prefab and null check that it is found, then inside our collision method set the animator to trigger our “OnEnemyDeath” parameter when either the player or laser collides with the enemy.
There are still a few more important steps. The first issue is that as it stands, this code will not execute the intended behavior because we are still destroying our enemy game object immediately after we are telling it to run the animation. Therefore the animation will never show.
This is a simple fix — we can just add a timing delay before we destroy the object, which matches the runtime of our animation, about 2.8 seconds.
The second issue stems from the solution to the first — because we are now not destroying our enemy object for another 2.8 seconds, there is now extra time for a destroyed enemy to still fall and collide with our player and cause damage. So, we could either disable the box colliders and allow the enemies to keep falling, or we could set speed to zero and freeze them in place when destroyed. I think the second option is better as we won’t need to deal with any enemies looping back to the top while destroyed but still mid-animation.
That behavior feels pretty good, and with that our enemy explosion effect is all done! In the next guide I’ll cover how to add a damage indicator for our player using animations. See ya there!