Is there a built-in way of controlling the time of an animation with a parameter in the Animator?

I have two animations: AimDown and AimUp. They are both 30 frames long. I would like to have a blend tree or something that goes from -1.0 to 1.0 and blends between these two animations according to that value. If the value is 0.5, frame 15 of the AimUp animation is played, if the value is -1.0, frame 30 of the AimDown animation is played and so on.

I know that if you have AimUp/Down animations that are just 1 frame long you can blend between these with a normal blend tree, but then the actual “animations” are just interpolations between these end states which doesn’t always look good.

I also know that you can accomplish this through script. I have done that before Mecanim and I’m sure you can do the same thing in Mecanim. What I’m asking is if perhaps there’s some extra/hidden possibilities in the actual Animator window that I’ve missed which would let me do what I want?

The only way to emulate this behaviour is by script with Animator.Play()
http://docs.unity3d.com/ScriptReference/Animator.Play.html

There is no way to change a state timing with an Animator’s parameter.

Thanks. I got it working. With more or less the exact code from the Unity 3.x Bootcamp project no less. :slight_smile: I’m currently using the Bootcamp soldier for my prototype so that was pretty cool.

Here’s the code for anyone else coming in here. aimTarget is the position I want to aim towards. aimPivot is the spine3 bone of the soldier, just like in the Bootcamp project.

I’m not sure if the Animator code can be tweaked. I’m sure I’ll find out as I fiddle more with this. In my Animator I just have 2 states “StandingAimUp” and “StandingAimDown” which I switch between depending on the AimUp boolean. These are on a separate layer so I can aim independent of the other animations playing. And with Mecanim I can use the same AimUp/Down animation for standing or crouching as well because I can just mask out the feet.

void Update() {
    Vector3 aimDir = (aimTarget.position - aimPivot.position).normalized;
    float aimAngleY = Mathf.Asin(aimDir.y) * Mathf.Rad2Deg;

    if (aimAngleY > 0) {
        animator.SetBool("AimUp", true);
        animator.Play("StandingAimUp", 1, Mathf.Clamp01(aimAngleY / 90));
    }
    else {
        animator.SetBool("AimUp", false);
        animator.Play("StandingAimDown", 1, Mathf.Clamp01(-aimAngleY / 90));
    }
}
2 Likes