Search Unity

Transition Settings in StateMachineBehaviour

Discussion in 'Animation' started by U-GeeN, Apr 20, 2015.

  1. U-GeeN

    U-GeeN

    Joined:
    Mar 22, 2015
    Posts:
    95
    I know that issue was brought up quite a while ago and I cant find the thread anymore...
    So heres the deal:
    Is it possible to access the transition settings of the next transition from within the StateMachineBehaviour? upload_2015-4-20_7-39-50.png
     
  2. waythewanderer

    waythewanderer

    Joined:
    Apr 6, 2015
    Posts:
    92
  3. U-GeeN

    U-GeeN

    Joined:
    Mar 22, 2015
    Posts:
    95
    I found the Settings in AnimatorStateTransition.
    Is it even possible to reference AnimatorStateTransition in StateMachineBehaviour?

    Or is there some easier way to start "SwingTree" at any point in "PrepTree".
    But if PrepTree is at 100%, SwingTree must start at 0%
    if PrepTree is at 0%, SwingTree must start at 50% (or 100% if I split it up)
    So it has to be kinda inversely proportional.
    Any suggestions?
     
    Last edited: Apr 21, 2015
  4. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    No, AnimatorStateTransition is an editor only class.
    If you want some kind of dynamic transition between two state you should use a StateMachineBehaviour and
    Animator.CrossFade
    http://docs.unity3d.com/ScriptReference/Animator.CrossFade.html

    This function allow you to create a one time dynamic transition. you could use the AnimatorStateInfo from the StateMachineBehaviour to compute your start time.

    Code (CSharp):
    1. public class PreTree : StateMachineBehaviour {
    2.  
    3.     int swingTreeHash = Animator.StringToHash("SwingTree");
    4.     // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    5.     override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
    6.         if (myConditionToStartATransition)
    7.         {
    8.             animator.CrossFade(swingTreeHash, 0.05f, layerIndex, 1.0f - stateInfo.normalizedTime);
    9.         }
    10.     }
    11. }
     
    Krull and codegasm like this.
  5. U-GeeN

    U-GeeN

    Joined:
    Mar 22, 2015
    Posts:
    95
    Wow, a developer is helping me!
    Using CrossFade seems to work. Thanks a lot! My animations are much clearer.
    It gets stuck sometimes for a moment as if there was an "ExitTime" somewhere...
    And another thing, is it possible to assign speed to different States or even StateMachines in scripts?
     
  6. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Of course we are, Unity would not be what it is today without our commUnity ;)

    This is a new feature in 5.1 which is in beta stage right now, stay tune

    What exactly is getting stuck?
     
    io-games likes this.
  7. U-GeeN

    U-GeeN

    Joined:
    Mar 22, 2015
    Posts:
    95
    I found my mistake...
    It CrossFade should be fired only once, or else...
    But now I have some State that isn't connected to its next State and transits thrugh magic.

    Thanks again anyway, at least its working :)
     
    Last edited: Apr 24, 2015
  8. U-GeeN

    U-GeeN

    Joined:
    Mar 22, 2015
    Posts:
    95
    I noticed some other odd behaviour...
    I have a simple timed transition (animA -> animB via hasExitTime).
    When I increase the Animator.speed, my animation animA stays some time in its last frame till it finally transits to animB.
    How can I start a transition when animA is finished, independently from the animator.speed?
     
  9. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    The only thing that animator.speed does is to scale delta time that we get from the engine when we get tick.

    We never heard of any issue with transition and changing animator.speed, if you can't figure out what is going on you can log a bug with your project and some repro step.
     
  10. U-GeeN

    U-GeeN

    Joined:
    Mar 22, 2015
    Posts:
    95
    Its probably because of the CrossFades normalized time.
    hasExitTime=1 waits till animation is played out, but if animation starts with an offset and has no loop time, it simply waits in its last frame.
     
    Last edited: Apr 26, 2015
  11. U-GeeN

    U-GeeN

    Joined:
    Mar 22, 2015
    Posts:
    95
    I used to start an AnimationEvent that played a sound in the first frame of "SwingTree".
    But with CrossFade the AnimationEvent starts only if stateInfo.normalizedTime = 1.
    How is it possible to play a sound with the start of animation
    ?
     
  12. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Animation Events should always be fired if they are in the playback range.
    You should log a bug.

    The only other reliable way is to use StateMachineBehaviour.OnStateEnter()
     
  13. U-GeeN

    U-GeeN

    Joined:
    Mar 22, 2015
    Posts:
    95
    Uhm... pardon my icompetence...
    AudioSource.PlayClipAtPoint()
    Is there a way to acess a static MonoBehaviour variable in StateMachineBehaviour so I can control the volume in all sound playing StateMachineBehaviours?
    Or is there a better way to do that?
     
  14. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    if the monobehaviour is on the same game object than your animator then you should be able to retrieve it with something like this

    public override void OnStateEnter(Animator animator, ...) {
    MyMonoBehaviour behaviour = animator.GetComponent<MyMonoBehaviour>();
    }
     
  15. U-GeeN

    U-GeeN

    Joined:
    Mar 22, 2015
    Posts:
    95
    Is it possible to start next State with an offset via the new Cycle offset parameter instead of crossfade?
    Or is it only meant for looping animations so they only play from the beginning the first cycle?
    Is there another cleaner way to accomplish that?