NAV Navbar
csharp

Introduction

Sometimes you just want to run a simple animation from code, without all the overhead... adding multiple components to your game object, managing a timeline with key frames, transitions, etc.

Something like button.Go().Scale(1.25f, 0.5f, Ease.Bounce.Out) would be great. Done. Now all your buttons animate with a satisfying little bounce whenever a user clicks on them.

This type of animation, that doesn't involve full-blown timeline and key frame management, is sometimes called "tweening".

It would be nice to be able to animate anything in Unity like that, with just a line or two of C#. UI elements, shader variables, colors, camera or light properties. Anything.

Or, maybe you'd just like to organize more complex animation sequences in code, without a lot of setup in the editor. These might involve nested chains of animations triggered by state changes, with sophisticated easing algorithms. Of course, you also want to be able to transition smoothly between animations when moving from one state to another. That means you need to be able to interrupt in-progress animations gracefully.

Mezzanine Tweens is a simple, but powerful, programmatic animation library for Unity, that enables these kinds of scenarios for you.

The library uses C# extension methods to add this functionality to all your game objects automatically. So, you can call myGameObject.Go() on any object, then simply follow the easy to use method-chaining syntax, and let the code completion features of your dev environment do the rest.

There are built-in methods for animating the position, rotation, and scale of any object in your game, including UI elements.

A collection of elegant easing algorithms apply natural acceleration and deceleration to your animations.

The library includes facilities for nesting and chaining animations, interrupting animations, and monitoring the progress of animations.

In addition, features are including to enable the easy animation of any collection of numeric values in your game. So, you can animate everything from shader variables to data attributes.

And, if you want to use the editor to set up and organize your animations, no problem. The package includes straight-forward editor tools that allow you to attach animation groups to your game objects in the hierarchy panel and modify corresponding values in the inspector. You can preview animations right in the editor, without the need to compile and run your game. You can nest animation groups and trigger groups of animations in response to events, right in the editor. All without a single line of code. The editor tools will even generate code for you, so you can test animations visually in real-time, then just paste the code into your C#, if you prefer to work in code.

Mezzanine Tweens, like all Mezzanine products, is open source. It's comprised of simple, well-organized and documented code. So, you can customize it any way you like to meet your needs.

While Mezzanine Tweens was developed for and tested with Unity, it can be used in any C# project, and holds no external dependencies.

Quick Start

Some simple examples:

myGameObject.Go().Position(x, y, z);

myGameObject.Go().Scale(1.5f, duration, ease);

myGameObject.Go().Pause(3f).Then(animation => {
    if (!animation.IsInterrupted) gameObject.Go().RotationY(180f);
});

The Go object can be passed by reference:

var go = myGameObject.Go();

myCustomAnimationFunction(go);

Every animation method returns an Animation object:

var animation = myGameObject.Go().PositionX(600f, 0.5f);

myButton.Component.onClick.AddListener(() => {
    if (animation.IsPaused) animation.Unpause();
    else animation.Pause();
}));

Default values:

Go.DurationDefault = 0.65f;

Ease.Default = Ease.Exponential.InOut;

Once you've imported Mezzanine Tweens into your game project, you'll be able to animate any gameObject in your game using the Go() extension method, as illustrated in the examples to the right. Simply call the Go() method on any gameObject and use code-completion to select an animation method.

All of the built-in animation methods follow a consistent format with some common parameters, as described below.


PARAMETERS


PARAMETER DESCRIPTION
duration A float representing the time span of the animation in seconds. The default duration of 0.6 seconds can be changed by setting the static Go.DurationDefault property to the desired value.
ease The easing algorithm to apply. All the built-in easing algorithms can be accessed as static properties on the Ease class, such as Ease.Quadratic.InOut. The default easing algorithm is set to Ease.Quintic.Out, which works very well for subtle deceleration on things like UI elements. But, this can be changed using the Ease.Default property. If you wish to turn off easing altogether, set Ease.Default = Ease.Linear.None
isOffset If false (default), the values provided will be taken to denote a destination target relative to the parent game object. If true, the values will be added to the game object's current state as an offset.
isLocal Set to false, if you wish to specify animation values in world space, rather than local.
repeatCount 0 (default) = Don't repeat the animation.

1 = Reverse the animation when the target is reached and return to the start.

2+ = Repeat the animation the specified number of times, returning to the start at the beginning of each new cycle.

-1 = Repeat the animation indefinitely, unless it is interrupted manually.

The Animation object

All animation methods return an MzAnimation object, which can be used to monitor the progress of an animation. This allows you to pause, or interrupt the animation at any time. You can also use this object to initiate additional animations, or to invoke some other code, when the animation has completed, or has been interrupted by another process.


EVENTS


The Updated event:

var animationScale = go.ScaleXyz(animationKey, 1.5f, 1.0f, Ease.Elastic.Out, false, 1);

AnimationEventHandler onUpdated = (object sender, AnimationEventArgs args) =>
{
    // You can do whatever you want here. 
    // args.Progress will hold a value from 0 - 1, 
    // representing the current progress of the animation.
    // For example, a value of 0.5 would indicate that 
    // the animation is halfway done.
    var colorLight = Color.Lerp(Core.Colors.Highlight, Color.green, args.Progress);
    light.color = new Color(colorLight.r, colorLight.g, colorLight.b, _light.color.a);
};

// Here, we attach the action we want to run every time the animation is updated.
animationScale.Updated += onUpdated;

There are several events associated with the Animation object that you may find useful for tracking the progress of the animation.

EVENT DESCRIPTION
Updated This event is triggered at the beginning of each Update() cycle, as the animation progresses. This event can be used to animate any collection of numeric values in your game (as will be described more fully below).
Paused This event is triggered whenever the animation is manually paused using the Pause() method on the Animation object.
Completed Triggered when the animation has completed. You can determine whether the animation was interrupted by checking the IsInterrupted property.

Using the Updated event to animate anything

Using the Updated event to fade out a 3D primitive:

// In this case, we want the 3D primitive to fade out when 
// the user changes screens. We can affect the transparency 
// of the primitive by modifying the alpha value of its 
// associated material. We can grab this from the MeshRenderer.
var meshRenderer = myPrimitive.GetComponent<MeshRenderer>();

// Animating the value is really easy. With just a call to a 
// single static method, we'll animate it from its current value 
// to 0 in the default time duration and easing algorithm.
var colorCurrent = meshRenderer.sharedMaterial.color;
var animationAlpha = Go.Value(colorCurrent.a, 0);

// This will give us a new value for each update of the animation, 
// which we can then apply to the material directly. Any value 
// can be animated in this way, including shader variables, data 
// attributes, camera and light properties. Anything.
animationAlpha.Updated += (object sender, AnimationEventArgs args) =>
{
    var colorNew = new Color(
        colorCurrent.r, 
        colorCurrent.g, 
        colorCurrent.b, 
        args.Value.Current // This holds our current alpha
    );

    meshRenderer.sharedMaterial.color = colorNew;
};

The Updated event is of special note, since it can be used to animate any numeric value in your game, beyond the built-in methods for animating game objects and UI elements which will be outlined in detail below.

For example, the code on the right shows how to fade out 3D primitive using the Updated event.


PROPERTIES


PROPERTY DESCRIPTION
Key A unique identifier that can be used to reference an animation. This is useful for managing interruptions and for transitioning smoothly between animations. See the Animation Keys section below for more information.
Progress This property will hold a float value between 0.0 and 1.0 representing the current progress of the animation, where 0.0 marks the beginning of the animation and 1.0 marks the end. This value is updated at the beginning of each Update() cycle while the animation is in progress.
IsPaused Is the animation currently paused.
IsInterrupted Was the animation interrupted before its target values were met?
IsCompleted Has the animation completed? Completion may have been forced by an interruption.
TaskCompleted A Task<IAnimation> object that can be used with the await keyword to wait for the animation to complete before continuing with a block of code.


METHODS


METHOD DESCRIPTION
Pause() Pause the animation.
Unpause() Unpause the animation.
Interrupt() Manually interrupt the animation. This will trigger the Completed event and set both the IsCompleted and IsInterrupted properties to true.
Complete(bool isInterrupted) Force the animation to complete immediately. This can be used in situations where you want to interrupt the animation, but you still want the animated values to be set to match the destination target values. This is in contrast to the Interrupt() method, which leaves the animated values in their current state at the time of interruption.
Then(Action action) The library supports async/await, so you can write code such as await animation.TaskCompleted;. Additionally, the Then() method is included as a convenience method. It provides the associated Animation object as an argument to action parameter.

Animation Keys

Use keys to allow animations to be interrupted:

myGameObject.Go().PositionX("my-object", 1000f, 2f);

await Go.Pause(1f).TaskCompleted;

myGameObject.Go().PositionX("my-object", 0f, 2f);

The above example could also be expressed in this way:

var animation = myGameObject.Go().PositionX(1000f, 2f);

await Go.Pause(1f).TaskCompleted;

myGameObject.Go().PositionX(animation.Key, 0f, 2f);

Animations can also be retrieved by key:

var animationExisting = Go.Manager.GetAnimation(animationKey);

When animations can be triggered dynamically by user interactions or changes in game state, it is often useful to allow those animations to be gracefully interrupted, so that we can transition smoothly to some other animation, or move on to a different process.

In these scenarios, we can use a custom key to identify the animation. If a new animation is started using the same key, the currently in-progress animation will be interrupted.

All the animation methods in the library provide a signature that accepts an optional custom key as the first parameter. If no key is provided, a unique key will always be generated automatically. This automatically generated key can be used by referencing the Key property on the Animation object.

In the example on the right, the 2 second animation will be interrupted halfway through and the game object will be smoothly transitioned to a different animation.

Animation Manager

The global animation manager provides several useful methods outlined below. The manager can be accessed by referencing Go.Manager.

METHOD DESCRIPTION
PauseAll() Pause all animations that are currently in-progress.
UnpauseAll() Unpause all paused animations.
Pause(duration, ease) Return an Animation object that simply waits for the specified duration before completing.
GetAnimation(key) Return the Animation object specified by the provided identification key.

Additionally, static methods are provided for each of the built-in animation methods. These can be accessed by calling a method on the Go class and passing in a gameObject to animate. For example: Go.Position(myGameObject, 100f, 100f, 100f, 1.ff).

Position

Animate the position of any game object in 2D or 3D space:

static Mz.Animations.MzAnimation Position(
    GameObject gameObject,
    float x = float.NegativeInfinity, 
    float y = float.NegativeInfinity, 
    float z = float.NegativeInfinity,
    float duration = -1,
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local,
    string key = null
);
Mz.Animations.MzAnimation Position(
    string key,
    float x = float.NegativeInfinity, 
    float y = float.NegativeInfinity, 
    float z = float.NegativeInfinity,
    float duration = -1,
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local
);
Animation Position(
    float x = float.NegativeInfinity, 
    float y = float.NegativeInfinity, 
    float z = float.NegativeInfinity,
    float duration = -1,
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local,
    string key = null
);
Animation PositionX(
    string key,
    float value, 
    float duration = -1, 
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local
);

Animation PositionX(
    float value, 
    float duration = -1, 
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local, 
    string key = null
);
Animation PositionY(
    string key,
    float value, 
    float duration = -1, 
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local
);
Animation PositionY(
    float value, 
    float duration = -1, 
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local, 
    string key = null
);
Animation PositionZ(
    string key,
    float value, 
    float duration = -1, 
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local
);
Animation PositionZ(
    float value, 
    float duration = -1, 
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local, 
    string key = null
);

The position of any game object can be animated, using the default values for duration and easing, simply by calling

myGameObject.Go().Position(x, y, z)

and supplying any or all of the target values for x, y and z. In a 2D context, the z value can simply be omitted, as it will be ignored. The same method call syntax applies to game objects used as UI elements on a canvas.

All the built-in methods for animating the position of game objects are documented to the right.

Rotation

Animate the rotation of any game object in 2D or 3D space:

static Animation Rotation(
    GameObject gameObject,
    float x = float.NegativeInfinity,
    float y = float.NegativeInfinity,
    float z = float.NegativeInfinity,
    float duration = -1,
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local,
    string key = null
);
Animation Rotation(
    string key,
    float x = float.NegativeInfinity,
    float y = float.NegativeInfinity,
    float z = float.NegativeInfinity,
    float duration = -1,
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local
);
Animation Rotation(
    float x = float.NegativeInfinity,
    float y = float.NegativeInfinity,
    float z = float.NegativeInfinity,
    float duration = -1,
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local,
    string key = null
);
Animation RotationX(
    string key,
    float value, 
    float duration = -1, 
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local
);

Animation RotationX(
    float value, 
    float duration = -1, 
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local, 
    string key = null
);
Animation RotationY(
    string key,
    float value, 
    float duration = -1, 
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local
);
Animation RotationY(
    float value, 
    float duration = -1, 
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local, 
    string key = null
);
Animation RotationZ(
    string key,
    float value, 
    float duration = -1, 
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local
);
Animation RotationZ(
    float value, 
    float duration = -1, 
    EaseFunction ease = null,
    CoordinateSpace coordinateSpace = CoordinateSpace.Local, 
    string key = null
);

The rotation of any game object can be animated by calling

myGameObject.Go().Rotation(x, y, z)

and supplying any or all of the target values for x, y and z. In a 2D context, the z value can simply be omitted, as it will be ignored. The same method call syntax applies to game objects used as UI elements on a canvas.

All the built-in methods for animating the rotation of game objects are documented to the right.

Scale

Animate the scale of any game object in 2D or 3D space:

static Animation Scale(
    GameObject gameObject,
    float x = float.NegativeInfinity,
    float y = float.NegativeInfinity,
    float z = float.NegativeInfinity,
    float duration = -1,
    EaseFunction ease = null,
    bool isOffset = false,
    string key = null
);
Animation Scale(
    string key,
    float x = float.NegativeInfinity,
    float y = float.NegativeInfinity,
    float z = float.NegativeInfinity,
    float duration = -1,
    EaseFunction ease = null,
    bool isOffset = false
);
Animation Scale(
    float x = float.NegativeInfinity,
    float y = float.NegativeInfinity,
    float z = float.NegativeInfinity,
    float duration = -1,
    EaseFunction ease = null,
    bool isOffset = false,
    string key = null
);
Animation ScaleXyz(
    string key,
    float value,
    float duration = -1,
    EaseFunction ease = null,
    bool isOffset = false
);

Animation ScaleXyz(
    float value,
    float duration = -1,
    EaseFunction ease = null,
    bool isOffset = false,
    string key = null
);
Animation ScaleX(
    string key,
    float value,
    float duration = -1,
    EaseFunction ease = null,
    bool isOffset = false
);
Mz.Animations.Animation ScaleX(
    float value,
    float duration = -1,
    EaseFunction ease = null,
    bool isOffset = false,
    string key = null
);
Animation ScaleY(
    string key,
    float value,
    float duration = -1,
    EaseFunction ease = null,
    bool isOffset = false
);
Animation ScaleY(
    float value,
    float duration = -1,
    EaseFunction ease = null,
    bool isOffset = false,
    string key = null
);

Mz.Animations.Animation ScaleZ(
    string key,
    float value,
    float duration = -1,
    EaseFunction ease = null,
    bool isOffset = false
);
Animation ScaleZ(
    float value,
    float duration = -1,
    EaseFunction ease = null,
    bool isOffset = false,
    string key = null
);

As with position and rotation, the scale of any game object can be animated by calling

myGameObject.Go().Scale(x, y, z)

and supplying any or all of the target values for x, y and z. In a 2D context, the z value can simply be omitted, as it will be ignored. The same method call syntax applies to game objects used as UI elements on a canvas.

However, since it's usually the case that a uniform scale should be applied to each axis, you'll typically want to call

myGameObject.Go().ScaleXyz(value)

passing in a single value.

All the built-in methods for animating the scale of game objects are documented to the right.

Value

Animate any numeric variable:

var myValue = 20f;
var animation = Go.Value(myValue, 40f, 0.5f);

You can then use the Updated event to update the variable as the animation proceeds.

animation.Updated += (object sender, AnimationEventArgs args) =>
{
    myValue = args.Value.Current
};

The Go.Value() methods:

static Mz.Animations.Animation Value(
    string key,
    double startValue,
    double targetValue,
    object duration = null,
    EaseFunction ease = null
);
static Mz.Animations.Animation Value(
    double startValue,
    double targetValue,
    object duration = null,
    EaseFunction ease = null,
    string key = null
);

Animate any arbitrary numeric variable from its current value to a given target value by calling the static Value() method on the Go class.

var animation = Go.Value(current, target, duration)

You can then use the Updated event to update the variable as the animation proceeds, as shown to the right.

Editor Tools

Mezzanine Tweens includes a full set of editor tools to allow you to create, preview, edit, and organize your animations without writing any code.

To get started, right-click on any game object in Unity's Hierarchy panel and choose Mezzanine/Tweens/Animation Group from the context menu.

Menu animation group

A new Animation Group object will be added as a child of the selected game object. Click on the Animation Group object to view it in the Inspector panel.

Animation group 01

Simply click Add Animation to add a new animation to the group. You can then directly edit properties of the animation in the editor. Click the Preview button to test your animation right from the editor, without the need to compile and run your game. When the preview has completed, your game object will be returned to its original state.

Move capsule

You can add multiple animations to an animation group. To run all the animations in a group from code, you can call the RunAnimations() method on the associated gameObject. You can also use the Unity inspector to associate the method with gameObject events, like the OnClick() event of a button, for example. Each Mezzanine Animation Group exposes its own events from the inspector as well, under the Events section.

Events

The Code section of each animation is of special note. Mezzanine Tweens automatically generates code you can use, if you would prefer to run your animation from script. By clicking into the text area of this section, you can copy the code and paste it into your own C# scripts.

Code

The Then section allows you to specify another Mezzanine Animation Group, which will be run once the current group has completed all its animations.

Then