Day 26 — Getting into VFX in Unity
Hey and welcome!
So currently we have ourselves a pretty functional game by this point, for the next few days we’ll be looking into ways to pretty up our game a bit. The first thing we’ll look into is an explosion sequence for our enemies!
First import yourselves a 2D explosion spritesheet into Unity if you’re able and then open up your Enemy prefab. Next open up your animation window or grab it from Window > Animation > Animation if you’ve misplaced it and then create a new animation and import it in.
Now if you were to run the game as is you may find that your enemies are continually exploding over and over without the player having a hand in it. The looping explosion is easy enough to fix by going into the inspector window for our new animation and uncheck the Loop Time option:
Here comes the fun part next, we’re going to be diving a little into the animator tool in Unity so that we can choose when the explosion animation plays. So let’s open that up, you’ll find it next to your new animation in the project view.
Right click anywhere in the animator and create a new state, set the state as the default and lastly right click your new default state and make a transition to your animation state which was the previous default state.
Next create yourself a parameter, set it as a trigger and then call it something along the lines of EnemyDeath.
Click on the transition arrow you made and select your EnemyDeath parameter in the conditions after you press the plus option and set it to true. With all that done your enemies will no longer explode right away.
The reason for this is because in your animator things start in the default state that you created, once in here it’s checking for that EnemyDeath condition to be true before it moves to the animation state. So let’s go ahead and write up some code to trigger that when the enemy object is destroyed.
private Animator _enemyAnim;
private Collider2D _collider;void Start()
_enemyAnim = GetComponent<Animator>();
_collider = GetComponent<Collider2D>();
}private void OnTriggerEnter2D(Collider2D other)
if (other.tag == "Player")
_enemySpeed = 0;
_collider.enabled = false;
else if (other.tag == "Laser")
_enemySpeed = 0;
_collider.enabled = false;
I’ve omited some of the non-relevant code but one of the main takeaways is that we’re caching a reference to the Animator component for our enemy in _enemyAnim.
This means we can get access to our parameters in our animator in order to set their values to our choose which is what’s happening here _enemyAnim.SetTrigger(“EnemyDeath”) that will automatically activate our trigger an set it to immediately play on either collision the enemy has with the player or laser.
If our EnemyDeath parameter was a bool we’d use something along the lines of _enemyAnim.SetBool(“EnemyDeath”, true) as an example of what we can do.
You may have noticed that I’m also caching a reference to the collider of the enemy, this is so we can disable it with _collider.enabled = false so that the player won’t be able to collide with it and take damage while the animation is playing through.
And as a little quality of life change we can set the _enemySpeed to 0 so that they’re not carrying on their path while exploding. The last takeaway from here is the 3.0f we’ve added to our Destroy() this actually let’s us control how long the object remains in the game before it’s destroyed, in this case we’ve set it to 3 seconds so that the animation will play out.
If we didn’t include that our enemy would just vanish from the game without the animation playing since we’re destroying the object and anything associated to it, such as an animator component used to handle our fancy new enemy explosion animation.
Alternatively you could also set up a Coroutine that waits 3 seconds before destroying the enemy.
With that you should have some pretty good looking explosions. You may notice above that there are some delays with the explosions, that can be fixed by going into the enemy animator, clicking on the transition arrow and unchecking the Has Exit Time box.
The reason this works is because our default state in the animator is constantly cycling through itself roughly every second, when the exit time is checked it waits for the current cycle it’s on before it moves onto our animation state. So if it’s 0.3 seconds through the current cycle when we destroy the enemy it needs to wait another 0.7 seconds before it transitions to the animation state.
Removing the exit time check means that it will transition to the animation state regardless of how far through the current cycle in the default state it is.