Introduction to Unity Animation

In this tutorial, you’ll learn the ins and outs of Unity animation by tossing pies at belligerent clowns. By Barbara Reichart.

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 4 of this article. Click here to view the first page.

Control State Switches Using Parameters and Conditions

Next you need to tell Unity when it should play the transition between Any State and Hit, as this should not happen automatically. You only want the Animator to switch to the Hit state when the clown is actually hit.

For this, you can use parameters and conditions. A parameter is a variable that you specify on the Animator. You can use it to define a condition for a specific transition to happen.

Here’s how it works in practice:

In the top left corner of the Animator View, select the Parameters tab. Click on the + button. From the drop-down menu, select Trigger. This creates a new trigger. Name it hit. That’s it! You are now the proud owner of your first parameter.

CreateParameterCropped

Next, select the transition arrow from Any State to Hit. In the Inspector, scroll to the Conditions section. Right now it reads “List is Empty.” Click on the + button. This adds the hit trigger as a condition.

AddConditionToAnimation

The transition will now be triggered once the parameter hit turns to true.

To try it out manually, drag and drop the Animator View right next to the Game View, so that you can see both at the same time. Run the game. In the Hierarchy, select the Clown. In the Animator View, click on the radio button after the hit parameter. You’ll hear the splatter sound, and then the clown resets. Great — your Animator Controller works as intended.

Hit Triggered Manually

Types of Parameters and Combining Conditions

Triggers are useful, but of course there are more parameter types you can use:

  • Float: Fractions (0.1, 0.999, 6.31, …)
  • Int: Whole numbers (1, 5, 13, 1005, …)
  • Bool: True or False
  • Trigger: Boolean parameter that is reset to false once consumed by a transition

Each type can be used depending on your requirements. For example, an Int could count how often the player hits the clown and play a special animation the 10th time.

Furthermore, you can assign default values to every parameter in the parameter list of the Animator View.

AssignDefaultValues

A Condition is used to decide when a transition should happen. You can define more than one condition on a transition. In this case, all conditions have to be met to trigger the transition.

You can also express that, for example, the clown should transition to the hit state if it is hit or if a time limit is up. To do this, create a second transition between the Any State and the Hit state. In the Inspector, you now see two transitions. For each transition, you can separately define the triggering condition.

MultipleTransitions

Bull’s Eye – Combine Animations and C# Scripts

By now you’ve seen how powerful and flexible Unity’s animation system can be, even without a single line of code. But, of course, messing around with code is great fun, so triggering animations from scripts is what you’ll learn next.

Trigger an Animation From Code

Before you can react to a collision, you need to be able to detect it. Unfold the Clown in the Hierarchy and select its child Skin. In the Inspector, click Add Component and choose Physics\Mesh Collider. In the new Mesh Collider Component, tick on Convex.

You can now see a thin green border around the skin of the clown. Granted, the shape does not perfectly fit the clown, but it’s close enough.

MeshCollider

Try it out. Run the game — the cake (because it also has a Collider) no longer flies through the clown.

To detect this collision in code, select Skin in the Inspector. Click Add Component, and select New Script. Name the script CollisionBehavior, set Language to C Sharp, and press Create And Add.

When another Collider touches the clown’s Mesh Collider, it triggers OnCollisionEnter. Open CollisionBehavior in MonoDevelop by double-clicking on the file in the Project Browser.

Add the following code inside CollisionBehavior above the line void Start():

// 1
public bool collided;

//2
void OnCollisionEnter(Collision collision) {
  if (!collided) {
    collided = true;
    // 3
    GameObject clown = gameObject.transform.parent.gameObject;
    Animator clownAnimator = clown.GetComponent<Animator> ();
    // 4
    clownAnimator.SetTrigger ("hit");
  }
}

Here’s what the code does:

  1. Creates a bool variable that remembers whether the clown already collided.
  2. Only triggers the animation if the clown has not collided yet. The next line sets collided to true to make sure you will only trigger the Hit animation once.
  3. Fetches the Clown GameObject, which is the parent of the current gameObject, then uses GetComponent to retrieve the Animator.
  4. Calls SetTrigger on the clownAnimator. This makes the animator go to the Hit state. For other parameter types, you can use SetFloat, SetInt, SetBool or ResetTrigger.

Run the game. Have a good throw. When you manage to hit the clown, it will make a splash sound!

Gotcha! (Taken by Seth Lemmons published under CC)

Gotcha!

Gotcha! (Taken by Seth Lemmons published under CC)

State Machine Behaviors: React to State Changes in Your Scripts

State Machine Behaviors allow you to script behavior that is state dependent. For example, you can make the clown shrink as long as it is in the Hit state. Give it a try:

In Unity, go to the Animator View and select the Hit state. In the Inspector, click on Add Behavior. Select New Script, name it ClownHitBehavior and press Create And Add.

Double-click on ClownHitBehavior to open it. You might notice that Unity already added a few methods which are commented out. Don’t worry about them yet — you will learn what each of them does soon enough. Instead focus on scaling the clown!

Unlike Alice, our clown shrinks when it comes in contact with cake. (from pixabay under CC0 Public Domain

Unlike Alice, our clown shrinks, when it comes in contact with cake. (from pixabay under CC0 Public Domain

Unlike Alice, our clown shrinks when it comes in contact with cake. (from pixabay under CC0 Public Domain

To do this, add the startTime variable inside the ClownHitBehavior.

float startTime;

This variable will store the time when the Hit state was entered. You can use this to control the speed of the animation depending on the actual time instead of the frame rate. This ensures that the clown shrinks at the same rate no matter how fast the game is running.

Next, look for the (commented out) OnStateEnter method. In this method, you set the value of startTime. Replace it with this:

override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
  startTime = Time.time;
}

OnStateEnter is called when the state machine enters the Hit state. With Time.time you retrieve the time in seconds since the start of the game. While not all that great for creating a clock, this is really sufficient for shrinking your clown :]

Next, look for the OnStateUpdate method and replace it with the following code:

override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
  GameObject clown = animator.gameObject;
  clown.transform.localScale *= Mathf.Lerp (1, 0, Time.time - startTime);
}

OnStateUpdate is called on every frame while the Hit state is active. In every frame, you adjust the scale of the clown.

For this you first need to find the Clown GameObject. As the script is running on the Animator Component, you cannot simply access it via gameObject like you did before. Instead, ask the animator variable of the method for its gameObject and then store this in the clown variable.

Next, change the Clown GameObject’s scale using Mathf.Lerp. This method linearly interpolates between two numerical values.

Take for instance two different points on the screen. One is y-positioned on the left at 0 and the other is y-positioned on the right at 20. Passing in a .50 to Math.Lerp will return a point in the middle.

Call Math.Lerp with three parameters: the two values it interpolates between, in this case 1 and 0, and the time in seconds since the Hit animation started. Lerp then calculates the resulting scale. For example, at 0 seconds it will return 1, at 1 second it will return 0 and at 0.75 seconds it will return 0.25.

Hit play and toss cake at the clown until you get a hit — the clown shrinks and never reappears. A short game indeed!

Hit Clown Disappears

  • OnStateEnter is called on the first frame of the state being played.
  • OnStateUpdate is called after Update of MonoBehaviors on every frame while the state the behavior it is attached to is playing.
  • OnStateExit is called on the last frame of a transition to another state.
  • OnStateMove is called instead of OnAnimatorMove on MonoBehaviors for every frame as long as the state is playing.
  • OnStateIK is called after Unity calculates Inverse Kinematics for a humanoid character — for example, to allow it to grab an item.
Note: In case you wonder what the other methods in a State Machine Behavior are for:
  • OnStateEnter is called on the first frame of the state being played.
  • OnStateUpdate is called after Update of MonoBehaviors on every frame while the state the behavior it is attached to is playing.
  • OnStateExit is called on the last frame of a transition to another state.
  • OnStateMove is called instead of OnAnimatorMove on MonoBehaviors for every frame as long as the state is playing.
  • OnStateIK is called after Unity calculates Inverse Kinematics for a humanoid character — for example, to allow it to grab an item.
Barbara Reichart

Contributors

Barbara Reichart

Author

Over 300 content creators. Join our team.