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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

How do I build my own stateMachinePathHash for use with StateMachineBehaviour.OnStateMachineEnter()?

Discussion in 'Animation' started by dinnes, Mar 26, 2015.

  1. dinnes

    dinnes

    Joined:
    Mar 25, 2015
    Posts:
    6
    I'm trying to find the actual UnityEditor.Animations.AnimatorStateMachine object that matches the stateMachinePathHash variable passed into StateMachineBehaviour.OnStateMachineEnter().

    Does anyone know how I can build up a stateMachinePathHash that I can match against this variable? I assume it's something like the combination of layerName/parentStateMachine/thisStateMachine passed into Animator.StringToHash(), but I'm not exactly sure.

    I'm trying to do something like this:

    Code (CSharp):
    1. // OnStateMachineEnter is called when entering a statemachine via its Entry Node
    2.     override public void OnStateMachineEnter(Animator animator, int stateMachinePathHash)
    3.     {
    4.         AnimatorStateMachine sm = FindStateMachine(animator, stateMachinePathHash);
    5.         //do something with sm
    6.     }
    7.  
    8.     private AnimatorStateMachine FindStateMachine(Animator animator, int stateMachinePathHash)
    9.     {
    10.         AnimatorStateMachine retVal = null;
    11.         string path = string.Empty;
    12.         AnimatorController ac = animator.runtimeAnimatorController as AnimatorController;
    13.         foreach (AnimatorControllerLayer layer in ac.layers)
    14.         {
    15.             string layerPath = Path.Combine(path, layer.name);
    16.             AnimatorStateMachine sm = layer.stateMachine;
    17.             string smPath = Path.Combine(layerPath, sm.name);
    18.             int pathHash = Animator.StringToHash(smPath);
    19.             if (pathHash == stateMachinePathHash)
    20.             {
    21.                 retVal = sm;
    22.                 break;
    23.             }
    24.  
    25.             retVal = FindStateMachine(sm, smPath, stateMachinePathHash);
    26.         }
    27.  
    28.         return retVal;
    29.     }
    30.  
    31.     private AnimatorStateMachine FindStateMachine(AnimatorStateMachine parentSm, string parentPath, int stateMachinePathHash)
    32.     {
    33.         AnimatorStateMachine retVal = null;
    34.         foreach (AnimatorStateMachine sm in parentSm.stateMachines.Select(s => s.stateMachine))
    35.         {
    36.             string path = Path.Combine(parentPath, sm.name);
    37.             int pathHash = Animator.StringToHash(path);
    38.             if (pathHash == stateMachinePathHash)
    39.             {
    40.                 retVal = sm;
    41.                 break;
    42.             }
    43.  
    44.             retVal = FindStateMachine(sm, path, stateMachinePathHash);
    45.         }
    46.         return retVal;
    47.     }
     
  2. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    You are aware that this script won't work at runtime. AnimatorStateMachine is an editor class only.

    What is your goal exactly?
     
  3. dinnes

    dinnes

    Joined:
    Mar 25, 2015
    Posts:
    6
    I just became aware of this fact, so I'm re-evauating how I'm going to do this. My goal is to choose a transition from the entry node of a state machine based on the transition destination state StateMachineBehaviour .

    I'm currently writing an export for the state graph so I can know what transitions are available from a given entry node of a state machine.

    It would be great if there was a way I could include the stateMachinePathHash for each state machine in this export, so I could look up the state machine's entry node transitions in my exported data.
     
  4. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,675
  5. dinnes

    dinnes

    Joined:
    Mar 25, 2015
    Posts:
    6
    What do I pass into StringToHash ? AnimatorStateMachine.name?
     
  6. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    AnimatorStateMachine.name only won't be enough, you need to generate the full path name

    start from the top most statemachine and append each child statemachine name separated with a dot.

    Ex: parentStateMachine.thisStateMachine
     
  7. dinnes

    dinnes

    Joined:
    Mar 25, 2015
    Posts:
    6
    Worked! Thank-you!