Backward animation in Mecanim

With Unity old animation system you could make speed = -1 and animation will play backwards - so easy! But with new mecanim you cannot do this — if you make negative animator speed you will get error in console.

In my scenario I have tutorial animation with 6 slides, on each slide player have buttons «prev» and «next» so it can move forward an backward between slides with nice animation. Because mecanim cannot do backward animation, I had to write comlex script to manage each frame of animation on Update(). Here it is and I hope It will help someone:

using UnityEngine;

public class Tutorial : MonoBehaviour
{
    const float slidePeriod = 1 / 3f;

    Animator animator;
    int stateHash;
    float curAnimTime;
    float totalAnimTime;
    float nextSlideTime;
    bool playForward;

    void Start()
    {
        transform.localPosition = Vector3.zero;
        animator = GetComponent<Animator>();
        stateHash = animator.GetCurrentAnimatorStateInfo(0).tagHash;
        totalAnimTime = slidePeriod * 5; //animator.runtimeAnimatorController.animationClips[0].length;
        animator.speed = 0;
        enabled = false;
        if (PlayerPrefs.GetInt("tutorialShown", 0) == 0)
            Show();
        else
            gameObject.SetActive(false);
    }

    void Update()
    {
        if (playForward)
        {
            curAnimTime += Time.unscaledDeltaTime;
            if (curAnimTime > nextSlideTime)
            {
                curAnimTime = nextSlideTime;
                enabled = false;
            }
        }
        else
        {
            curAnimTime -= Time.unscaledDeltaTime;
            if (curAnimTime < nextSlideTime)
            {
                curAnimTime = nextSlideTime;
                enabled = false;
            }
        }
        animator.Play(stateHash, 0, curAnimTime/totalAnimTime);
    }

    public void PlayForward()
    {
        playForward = true;
        nextSlideTime += slidePeriod;
        if (nextSlideTime > totalAnimTime)
            nextSlideTime = totalAnimTime;
        enabled = true;
    }

    public void PlayBackwards()
    {
        playForward = false;
        nextSlideTime -= slidePeriod;
        if (nextSlideTime < 0)
            nextSlideTime = 0;
        enabled = true;
    }

    public void ShowSlide(int slideNo)
    {
        curAnimTime = nextSlideTime = slidePeriod * slideNo;
        enabled = false;
        animator.Play(stateHash, 0, curAnimTime/totalAnimTime);
    }

    public void Show()
    {
        gameObject.SetActive(true);
        ShowSlide(0);
    }

    public void Done()
    {
        PlayerPrefs.SetInt("tutorialShown", 1);
        gameObject.SetActive(false);
    }
}

Animator states can be set to any speed, including negative. This has always been true for the editor environment, and with teh release of Unity 5.1 it’s also possible to change the speed of an animation state at runtime.

Runtime Animator State Properties (speed, mirror, cycleOffset) for 5.1

Alternatively, you could just duplicate your animation in the Animator tree, set the speed of the duplicate to -1 in the inspector, and just set the conditions for that animation to be the conditions of your backwards animation. I don’t like that you can’t modify speed via code anymore, but this is a pretty simple solution.

I just tested this out on an animation and it worked just fine. This way you could still setup all the blending and not have to mess with code if you didn’t want to.

Edit: As per Cherno’s post, glad to see they added it back in.

Hey, I’ve been working with Unity 5.3 and another way I found to do it was to create a new float parameter for the animator controller (call it ‘direction’) and then enable it as a multiplier parameter for the Speed (with Speed = 1) in the state you wish to play in reverse.

Then in the scripting I set ‘direction’ = -1f and the animation plays in reverse.

Animtor anim = GetComponent();
anim.SetFloat(‘direction’, -1);

Heres how I did it

1)in the animation clip you want to control the speed create a new state “animSpeed”

2)On the script attached to the object that plays the animation add

void Start () {

    //accessing the animation on the object to change the speed
    //create a animSpeed parameter in the animation clip you wish to control
    Animator anim = GetComponent<Animator>();
    anim.speed = animationSpeed;
}

Hope it helps :slight_smile:

87633-captureb.jpg