Search Unity

State transition duration dependent on source animation lenght

Discussion in 'Animation' started by Petr-Sovis, Jan 25, 2015.

  1. Petr-Sovis

    Petr-Sovis

    Joined:
    Feb 5, 2013
    Posts:
    10
    Hi,
    i have blending tree (idle x run)
    idle is long animation and looped, run short animation and it's looped as well

    I need to do transition from this state to another state in some short time (it's actually turn)
    the problem is that duration of the transition is somehow dependent on source animation length. Although both source animations are looped, length of the source depends on blending parameter and can go form 20sec (idle) to 0.7 sec (run) and therefore length of transition (duration) is dependent on blending parameter.

    So I need to do transition 7 frames long (7/30 sec) and in case i'm in idle it takes this time, when in run it takes 0.000 nothing (immediate switch). Or when I reedit -> in run 7 frames, in idle 100 frames.

    Is there possibility to specify duration of transition fixed for all occasions ?

    thanks
    Petr
     
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    No, everything is setup in normalized time. It work well if all clip from the blend tree are of similar length.

    I would suggest you to remove your idle clip from the blend tree if transition timing is important in this case
     
  3. Petr-Sovis

    Petr-Sovis

    Joined:
    Feb 5, 2013
    Posts:
    10
    Hello, thanks for reply,
    but I don't understand "to remove your idle clip from the blend tree". To move it where ? Or remove Idle completely ? idle and run are always (in my experience) very different from perspective of duration.

    Does the sub-state machine work the same ? Is it possible to create idle-move sub state machine and blend from the sub-state machine to other sub-state machines ? I couldn't find this working. I cannot create transition to/from sub-state machine.

    I cannot create transitions from all states - to all other states. This would introduce transition madness.

    Should I use this:
    // AnimatorStateInfo ai = m_Animator.GetCurrentAnimatorStateInfo(0);
    // float dt = m_FightPunchDt / ai.length;
    // m_Animator.CrossFade(m_AS_FallDown, dt);

    this is also problematic (when i change parameters during the transition) - destination state doesn't trigger end of animation, because "on exit" from fall is atomic and the length of source is changed during the transition.

    And I have another problem.
    When I trigger transition while another transition is in progress, the tree gets stuck in previous state. All transitions are marked "non-atomic".

    Thanks.
    Petr
     
  4. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Create another state for your idle clip and create a transition from this state to your blend tree state, this way the idle clip is not anymore in your blend tree so your transition duration will be more stable

    Transition to statemachine is a new feature in 5.0

    This is expected for interrupted transition, an interrupted transition keep the last evaluated pose while transitionning and blend this pose with the new destination state pose.
     
  5. Petr-Sovis

    Petr-Sovis

    Joined:
    Feb 5, 2013
    Posts:
    10
    I try to explain more
    i have A -> B -> C states with transitions,
    A to B has trigger 1
    B to C has trigger 2
    if I fire the trigger 2 while transiting from A to B it waits till current state is B and then it transits to C.

    There are situations I can't wait.
    All transitions are marked non-atomic.

    Thanks petr
     
  6. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    So you need to interrupt a transition.

    A transition can be interrupted only if it's not marked atomic and a higher priority transition is triggered.
    Transition priority is define by the order in which they appear in the transition list, the first one has the highest priority. Also Any state transition are always evaluated first even to define transition priority

    In this case AnyState -> Dying has the highest priority followed by
    Run -> Idle, Run -> Slide and Run -> Vault
    transition_priority_anystate.png
    transition_priority.png


    So in your case you would like transition B -> C to interrupt transition A -> B. It's not possible because both transition are not from the same state.

    So you have two choice:
    1. If you want to keep animation continuity you need to create a new transition either from A to C and place it above your transition A -> B or from Any state -> C.
    2. If you don't care about animation continuity, when you detect that you need to interrupt A->B call right away Animator.Play("B") and setup your parameter to start transition B -> C
     
    Petr-Sovis likes this.
  7. Petr-Sovis

    Petr-Sovis

    Joined:
    Feb 5, 2013
    Posts:
    10
    Thanks !
    Have another question though :) , will crossFade command work the same way ?
    If i crossfade from A to B and then crossfade from A to C will it work ? How crossfade manages priorities ?
    Thanks again
    Petr
     
  8. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Animator.Play and Animator.CrossFade are API function that control the statemachine flow of action. They will override anything setup in the StateMachine.

    Even if you are in an Atomic transition which normally cannot be interrupted, those two functions will interrupt the flow of action.
     
  9. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    @Mecanim-Dev
    @DavidGeoffroy

    Is that possible to add an option to let transition from Any State have lower priority than other transitions?
    I believe this is a quite useful feature. I give a sample scenario below (similar to your example).

    To prevent transition explosion for dying state, I define "AnyState -> Dying".
    I also want to customize the transition parameters (e.g. duration) between Flying and Dying. I found I cannot only change one specific transition duration on inspector of "AnyState -> Dying" by simply selecting the "preview source state". Thus, I create an extra transition, "Flying -> Dying", and customize its parameters.

    Assume both transitions above can be activated by a shared bool flag "PlayerHealthIsZero".
    Now, in the game, when I set "PlayerHealthIsZero = true", and I want to activate "Flying -> Dying" (but not "AnyState -> Dying").

    How can I do this if Any State transitions are always have the highest priorities?
    I have to give up using Any State transition in this kind of scenarios?
     
  10. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    As a workaround you could either add another condition on your Any state transition to control the priorities
    bool AllowAnyStateTransition
    or you could use Animator.CrossFade to dynamically transition from flying to dying/Any state to dying depending on the state of your object.
     
  11. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    I see. I will add some extra flags to "mute" the transitions from Any State when I don't want them.