Unity 3D: Animation Curves Explained

As part of the on going Unity 3D introduction articles FARM FIGHTERS programmer, Barnaby Smith talks about the Unity3D software used to create the game. This week Barnaby delves into Animation Curves and their multiple uses. If you’re thinking about a career in video game development, this series of articles will serve as an insightful introduction to the Unity engine, which is a useful learning tool as well as a great platform for creating games for a variety of devices. 

Kwalee use a mixture of technologies to create games for mobile, one of which is Unity3D. Unity is a game creation tool and game engine used for rapidly developing games for a range of platforms, such as iOS, Android, Web, PC, Mac and console.

The most fundamental difference between computer games and video is interactivity. Player actions drive and shape the gameplay and for almost all games this means that the experience is never the exact same for different people.

This interactivity facilitates games that behave differently whether it’s something as significant as producing different endings based on player actions throughout the game (such as in the classic point and click Blade Runner by Westwood Studios which featured 13 possible endings) or allowing variety in the way you complete missions such as in the Assassin’s Creed series where you can fight your way through dozens of enemies or stealthily climb across walls to make your strikes undetected.

At its most basic player interaction can be considered feedback to a form of player input. Making that feedback responsive and polished is crucial to a game that feels slick. Conversely games that do not respond well to input feel frustrating to play.

To ensure the game feels as polished as possible it’s important to expose variables that can be tweaked to get the best values possible. Unity excels in this area as its inspector driven design allows variables to be viewed and changed at run time.

One particularly useful feature of Unity3D that works hand in hand with the script inspector are animation curves. Animation curves can be used for many purposes such as controlling how something moves and controlling the rate of change that an object undergoes. This makes it great for something as complicated as vehicle physics, allowing you to achieve movement that feels great and is stable with significantly less work than implementing a physically based vehicle simulation. But they can also be used for other purposes including user interface transitions, colour changes and shader inputs.

At their simplest an AnimationCurve can be thought of much like sampling from a graph. The horizontal axis are the input values and the vertical axis are the output values. When you pass in an input your output is the vertical point on the graph that corresponds to the horizontal point you supplied.

Creating An Animation Curve

For a great explanation of how to use SerializeField check out the Unity Docs

While the official documentation says “You will almost never need this” many game studios actually enforce its usage instead of public fields because it ensures proper encapsulation for your game code by forcing other code to use properties or methods.

To use an AnimationCurve you must declare a field of type AnimationCurve in one of your scripts and bind that script to a game object. When you select that game object you’ll see the curve automatically in the script, ready to be set or modified using a built in curve editor. For example if you create a C# script called AnimationCurveExample.cs and add it to a game object:

using UnityEngine;

public class AnimationCurveExample : MonoBehaviour
{
        [SerializeField]
        AnimationCurve bobbingCurve;
}

It will produce the following result in the inspector for that game object:

As you can see next to the field name there’s a grey box. This box is actually a preview of what the curve looks like. Since we have not yet created a curve it appears blank. Clicking the grey box will reveal a dedicated animation curve editor:

There’s a number of presets at the bottom of the curve editor, clicking one of these changes the curve to the preset. Select the second preset and you should see something like this (you may need to zoom out a little by scrolling, you can also pan by holding alt and dragging with the mouse):

AnimationCurves are made up of points, or keys. Each key has both a horizontal and vertical position. Selecting a key and dragging it will allow you to change the position of a key. Holding shift after you start dragging will make the movement only occur in one axis (matched based on whether you’ve moved further in horizontal or vertical). Holding control (Windows) or command (Mac) will snap the position to a grid based on your level of zoom.

Curve Settings

Each key also has properties relating to how the key influences the curve, such as the tangent at that point. Right clicking a key will show a context menu:

When keys are set to auto you don’t have to worry about any tangents. Changing both the points to free smooth allows us to set the tangents manually, for example here I’ve tweaked the curve to be more like a smoothstep curve.

You can add a new point to the curve, by right clicking the curve and selecting Add Key:

Unlike the other two points you can see two tangent lines (if you don’t, right click the key and select Free Smooth).

In free smooth mode, both the in and out tangents are locked together. Changing one tangent changes the other:

In addition to the auto and free smooth modes already described, there are two other options that you’ll have noticed. Flat and broken. Flat is simply a special type of free smooth, where the tangent is perfectly horizontal. Broken however allows both tangents to be set independently:

Tangent Settings

In addition to the overall key mode options, you also have some options per tangent for both the in and out tangent. By default these are set to free, which allow you to manually control the tangent, there is also the linear mode. When two corresponding tangents are set to linear between the two keys there will be a straight line:

Changing the tangent to constant however, means that from this key to its corresponding neighbour the vertical value of the curve is the same and thus constant:

Wrap Modes

As you may have noticed there are also options at both the start and end of the curve. These are the wrap modes for sampling out of range of the curve, very similar to texture wrap modes if you’ve encountered them:

If your curve has an input range of 0 to 1 and you sample the curve with a higher value of say 1.5, then the right most wrap mode is used to calculate the value that should be returned. If you sample with a smaller value than the range, such as -0.5 then the left most wrap mode is used. There are three options, the default clamp means that the output value from the edge of the curve will be used for all out of bounds sampling. Changing the right mode to loop will mean you’re your input value is wrapped into the correct range, this is visualised in the curve editor as:

Using a ping pong mode is similar except the looping is reversed for each alternating repeat, as shown here:

Programmatically Sampling A Curve

Sampling from a curve couldn’t be easier, each curve object exposes a method called Evaluate which simply takes a float input parameter. For this example I modified the above C# class to set the vertical position to a value sampled from the curve over time.

using UnityEngine;

public class AnimationCurveExample : MonoBehaviour
{
float timer = 0;

[SerializeField]
AnimationCurve bobbingCurve;

void Update ()
{
// Set the position’s Y value from the sampled value on the curve
Vector3 localPosition = transform.localPosition;
localPosition.y = bobbingCurve.Evaluate(timer);
transform.localPosition = localPosition;

// Increase the timer by the time since last frame
timer += Time.deltaTime;
}
}

Make sure you set the right most wrap mode on your curve to loop or ping pong (otherwise after sampling through the curve once, the output value will be clamped to the same value.)

I went for a sinusoid curve:

As soon as you hit play you should see the object move vertically according to the curve you’ve used. This is a simple example of how you can use an animation curve, but I’m frequently finding new uses for them virtually every week.

If you missed the first instalment of the Unity 3D articles don’t worry, it’s still on-line HERE

 By Barnaby Smith – FARM FIGHTERS Programmer