Unity Dev: Logical Animations

Previously we’ve set up animations for our Powerup objects, but they’re just a set of sprites animating in a never-ending loop. That’s obviously not going to work for everything we want to animate.

For example… let’s blow up some alien ships.

Ka-BOOM!

Thinking it Through

  1. We want the alien ships to explode only when they’re hit by a laser or are hit by our Player.
  2. We don’t want this animation to loop endlessly.

And… that’s it really. So let’s take a look and see how that’s done.

Double-click your Enemy prefab to open it up in your Scene window. Find your “Animation” window and hit “Create”.

Note: You’ll want to be sure that you’re adding the animation to the object that your Enemy’s Sprite Renderer component are on. I have my Enemy object as a parent to another object called “Enemy_Sprite” which is where the Sprite Renderer lives.

This will prompt you to save the animation controller and accompanying animation clip so do so in your Assets > Animations folder and call it “Enemy_Destroyed_anim” (or whatever you like, I’m not your boss).

I have a collection of sprites to use for this animation, so find yours, select them all and dump them into the Animation window.

Frame by Frame Explosion

Now we’ve got our animation, but if you run your game you’ll just see progressively more and more infinitely repeating explosions flying across your screen which is not… exactly what we want, though it is kind of fun.

First thing’s first, let’s stop the looping animation. Open up your Animations folder and view your animation clip in the Inspector. It’s the one that has an icon that looks like a triangle going really fast.

From here, simply untick “Loop Time” and that’ll stop the animation from looping.

Next up, we want to only trigger this animation when a laser or our ship collides with the Enemy. Double-click the animation controller whose icon looks like 2 squares playing an eternal game of tag, and you’ll see something like this.

This is the place where we can add logic to our animations. As it is, the entry point will drop you directly into the Enemy_Destroyed_anim node (which represents our Animation Clip), play the clip, and then be done because we turned off Loop Time.

First step is to create the idea of triggers. Open the Parameters tab and use the + symbol to create a new Trigger called OnEnemyDeath

Create a new Empty state by right-clicking anywhere in this area and then right click on the new node and choose “Set as Layer Default State”. Now our enemies won’t jump directly to their explosion animation, but we still need to add our logic in.

Right-click the Empty node again and “Make Transition”. Attach the transition arrow to “Enemy_Destroyed_anim” by clicking on that node.

Clicking on the white arrow representing the transition between “Empty” and “Enemy_Destroyed_anim” will give us access to some settings in the Inspector that we want to tweak.

Check off “Has Exit Time” and change the value of “Transition Duration” to 0. This will ensure that, as soon as our Trigger is activated, we’ll go right into the explosion animation. If this weren’t done, we’d have an awkward moment where we hit the enemy with a laser… and then it takes a couple seconds to realize it and only then proceeds to go into an overly dramatized Shakespearean death scene.

Finally, add a Condition. Since we’ve only established the one Parameter, it’ll auto-populate.

Time for Code

Begin by getting a reference to your Animator component in your Enemy script.

Enemy.cs
Null check, null check, null check

Note: I use GetComponentInChildren to fetch my Animator component because my Sprite Renderer, and now Animator, components are on a child object to my Enemy object.

It’s as simple as adding _anim.SetTrigger(“OnEnemyDeath”); where it’s needed.

One last important thing. We’ve done all this great work, and if you were to run your game, you’d see absolutely none of it. As soon as we hit an Enemy with our Laser, we Destroy() that Game Object and with it goes the Animator we just lovingly crafted.

Have no fear, it’s a quick fix. The Destroy() method accepts an addition, optional argument which will dictate how long after it’s called to actually destroy the object.

Enemy.cs::OnTriggerEnter2d

Happy exploding!

On a quest to become a game developer. Still sometimes providing unsolicited advice about how to function in society.