Search Unity

CrossFadeQueued for Mecanim ?

Discussion in 'Animation' started by manutoo, Jun 18, 2014.

  1. manutoo

    manutoo

    Joined:
    Jul 13, 2010
    Posts:
    523
    Hello,

    we got CrossFade for Mecanim, but still no CrossFadeQueued.
    Does anyone know if it'll be coming before end of this year ?

    If not, what's the best way to implement it by myself ?

    Right now, I have a very simple system using legacy animation, but I might need to handle as well Mecanim as I'm planning to buy some characters on the Store that come without animation.

    So right now, I have this :
    Code (csharp):
    1. Play(MyNewAnim)
    2. {
    3.   animation.CrossFade(MyNewAnim);
    4.   animation.CrossFadeQueued(InBattle ? MyBattleIdle : MyIdle);
    5. }
    I can easily replace CrossFade by using the Animator's one, but for CrossFadeQueued, I'm not sure what to do.
    I guess I could create a state machine with a transition depending of an InBattle boolean to go back to BattleIdle or Idle, but it means I'd have to manually add that to all my anims, and thus make the process of adding anim (or worst, creating new controller) more painful & error prone.

    I could also add an event at end of each anim, but again, it'd require grunt work for all anims.

    The only other solution I see is to poll on each frame if the current anim ended already, and if yes, start the correct idle anim. But performance & clean wise, it may not be a great choice.

    Any thought ?
    Thanks in advance for any advice ! :)
     
    Last edited: Jun 18, 2014
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    There is no Animator.CrossFadeQueued and it not on our road map for now

    There is a distinction in Mecanim between a state and a clip. In Mecanim you don't play a clip but a state which may containt many clip if this state is a blend tree.

    So I don't understand why you say that you have to add that to all your anim. You only need to create two state: Battle state with a transition to BattleIdle state.
     
  3. manutoo

    manutoo

    Joined:
    Jul 13, 2010
    Posts:
    523
    Mecanim.Dev,
    thanks for your answer.
    Let me clarify a bit.
    Let put aside the Idle vs BattleIdle for now, just let concentrate on the transition issue.
    For example, I have these 3 anims : Attack1, Attack2, Attack3. Each of these anims will be in a state with the same name.
    When I CrossFade to any of them, I want them to go to BattleIdle after they finish. It means, I'll have to manually add 3 transitions in my Controller state machine graph.
    Now, I'll have about 40 creatures in my game ; that means I'll have to add 120 transitions if I have to create 1 controller per creature. That's a lot of dummy work to replace 1 line of code, isn't it ? (and I'd have to do that for some other non-looping animations as well)
    Fortunately, I should be able to create only 1 controller and use it with most of my creatures (if not all), replacing the clips by a script using AnimatorOverrideController (although at this point I'm not sure how I'll collect the list of replacing clips), so it should keep the grunt work under an acceptable amount (ie: 15-30 transitions max to replace my 1 line of code).

    Back to the Idle vs BattleIdle ; to avoid to have 2 exit transitions for each attack, I guess I could make them all transition to BattleIdle, and then in BattleIdle I'll add a exit transition to Idle that triggers when a "Battle" boolean is false (with or without an exit time). That should work well enough for my purposes.

    PS:
    doc isn't up to date :
    - http://docs.unity3d.com/Manual/AnimationParameters.html -> I don't have any "Vector" parameter in my Unity 4.5.0f6 , and I have a "Trigger" but it's not explained in that page (I know what it does thought, as it's explained in the Forum)
    - http://docs.unity3d.com/Manual/class-Transition.html -> no word about the new "Can transition to self" option (and I kinda wonder what it does, and google cannot find any reference to it)
     
  4. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    You have two option:

    Either your controller is for a humanoid rig and you reuse it for all your avatar, in this case you define your transition only once.
    Or you create a controller and use it as a template with an AnimatorOverrideController, again you define your transition only once and change clip with the override.

    Performance wise it will be faster than using script to queue your clip, everything will be managed on the C++ side directly by the animation engine rather than switching from c++ to script to c++

    We are aware that doc may be not up to date, when you find such case please log a bug it will help us to track down what is missing or incomplete.

    Vector parameter has been removed since 4.3.
    Can transition to self allow you to create a transition with the same source and destination state.

    Best regards,
     
  5. manutoo

    manutoo

    Joined:
    Jul 13, 2010
    Posts:
    523
    Ok, I'll try all this ; thanks for your answer !
     
  6. xCyborg

    xCyborg

    Joined:
    Oct 4, 2010
    Posts:
    633
    Please add queued playback for mecanim, this is really lacking even compared to legacy animation.
     
  7. Skunk-Software

    Skunk-Software

    Joined:
    Sep 24, 2014
    Posts:
    4
    Replying since this is the #1 result on Google for "Mecanim CrossFadeQueued".

    My work-around:
    (best explained in code, below)
    Code (CSharp):
    1. if(previousAnimation != currentAnimation)
    2.             {
    3.                 if (MyAnimator.IsInTransition(0))
    4.                 {
    5.                     // Prevents the crossfade 'bug'
    6.                     // I figured out the crossfade 'bug', it happens when a crossfade doesn't finish before calling it again
    7.                     // Like if crossfade to fall right above ground, then crossfade to idle on land (before crossfading fully to fall)
    8.                     // So 'skip' till the current crossfade completes
    9.                 }
    10.                 else
    11.                 {
    12.                     Debug.Log("Switch Animation: " + currentAnimation);
    13.                     previousAnimation = currentAnimation;
    14.                     MyAnimator.CrossFade(currentAnimation.ToString(), 0.12f);
    15.                 }
    16.             }
     
    SpacePilot1000 likes this.
  8. SpacePilot1000

    SpacePilot1000

    Joined:
    Dec 23, 2013
    Posts:
    7
    Thanks for posting this. I was having problems with trying to crossfade while a previous crossfade was still in progress. Your post provides much needed clarity, now I understand what is going on!