Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Recreating Animator.CrossFade State

Discussion in 'Animation' started by aerlandson, Dec 6, 2016.

  1. aerlandson

    aerlandson

    Joined:
    Feb 1, 2014
    Posts:
    2
    I'm having difficulties using the Animator API to precisely recreate a particular crossfaded state between two animations.
    Specifically, I want to use CrossFade (or CrossFadeInFixedTime) to immediately set the animator to a state partially blended into the second state.

    I'm aware that I can use the fixedTime parameter in Animator.PlayInFixedTime to set the animation to a particular time.
    Code (CSharp):
    1.  
    2. animator.Play("State1", 0);
    3. // an unknown number of animator.Update calls, over the duration of someTime
    4.  
    5. // Attempting to recreate the exact same animation state
    6. animator.PlayInFixedTime("State1", 0, someTime); // This appears to recreate the same state as if I iteratively called Update
    7.  
    However, I'm not having luck doing the same with CrossFade / CrossFadeInFixedTime.

    Code (CSharp):
    1.  
    2. animator.Play("State1", 0, 0);
    3. animator.CrossFadeInFixedTime("State2", crossFadeDuration, 0);
    4. // an unknown number of animator.Update calls, over the duration of someTime
    5.  
    6. // Attempting to recreate the exact same animation state
    7. animator.Play("State1", 0, 0);
    8. animator.CrossFadeInFixedTime("State2", crossFadeDuration, 0, someTime); // This does not recreate the same state as if I iteratively called Update.
    9. // The crossfade would now begin crossfading for the full duration; I instead want the animator to be someTime into the crossfade
    10.  
    I've tried several combinations of using Animator.Update(deltaTime) to skip the animator into the desired partially-crossfaded state:

    Code (CSharp):
    1.  
    2. animator.Play("State1", 0, 0);
    3. animator.CrossFadeInFixedTime("State2", crossFadeDuration, 0, 0);
    4. animator.Update(someTime);
    5.  
    However, this doesn't seem to do what I want it to, either; the animator appears to skip the crossfade entirely.

    Am I misunderstanding how to use the Play/CrossFade/Update calls? It seems strange that I can't use some combination of them to recreate a particular crossblended state.
     
  2. aerlandson

    aerlandson

    Joined:
    Feb 1, 2014
    Posts:
    2
    It seems that this relies on some internal functionality of animator.Update.

    These two blocks of code aren't functionally identical, as I would have expected:
    Code (CSharp):
    1. for (int i = 0; i < 10; ++i)
    2. {
    3. animator.Update(deltaTime);
    4. }
    and

    Code (CSharp):
    1.  
    2. animator.Update(10 * deltaTime);
    I've found a tentative solution that involves manipulating the speed of the animator:

    Code (CSharp):
    1. // Assumes animator.speed == 1
    2. animator.Play("State1", 0, 0);
    3. animator.CrossFadeInFixedTime("State2", crossFadeDuration, 0, 0);
    4. animator.Update(0);
    5. animator.speed = someTime;
    6. animator.Update(1);
    7. animator.speed = 1;
    It's not pretty, but so far it seems to accomplish what I'm looking for, and sets the animator into a state that is partially crossfaded between the two states.

    Does anyone know why animator.Update(10 * deltaTime) doesn't produce the same behavior as 10 calls to animator.Update(deltaTime)?
     
  3. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    I'm trying to do exactly that right now. There seems to be a normalizedTransitionTime parameter in CrossFade and CrossFadeInFixedTime now but I'm not getting the results I'm expecting with that either.

    I was wondering if the animationTime of both anims had to be the time at the begining of the transition or at the transitionTime we are trying to recreate.
     
  4. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    So I've been trying animator.Update(transitionTimeToRestore) and that method above of manipulating animator.update + animator.speed, and it's still not resuming the animations and transition state properly.

    I'm trying to switch an entity rendered using DrawMeshInstancedIndirect and animated using a special shader with a standard GameObject+Animator character at runtime when physics interactions are required. It works flawlessly, except while in transition. I can't seem to restore the proper animation and transition offset/timing.

    There may also be some confusion in the terms used in the doc (from what I read on the forum)...
    I'm quite lost.
     
    Last edited: Oct 3, 2022