Reputation: 2884
I'm using the following structure:
(Layer) "Base Layer" --> (Sub-State) "Jump_Fall_Roll" --> (State) "Roll"
static int rollState = Animator.StringToHash("What to put here??");
private Animator anim;
private AnimatorStateInfo currentBaseState;
void Start ()
{
anim = GetComponent<Animator>();
}
void FixedUpdate ()
{
currentBaseState = anim.GetCurrentAnimatorStateInfo(0);
if (currentBaseState.nameHash == rollState) {
Debug.Log ("ROLL nameHash worked"); //Not working
}
if (currentBaseState.IsName("Roll")) {
Debug.Log ("ROLL IsName worked"); //Working.......
}
}
I tryed every possible combinaison of parents/states for the nameHash, but it never worked...
The name should be in the form Layer.Name, for example "Base.Idle".
AnimatorStateInfo.IsName doc from Unity
So, why is my first case not working? And how can the second case work??
I'm really confused.
EDIT
Screenshot of my Animator view
I did try static int rollState = Animator.StringToHash("Base Layer.Roll");
Then Debug.Log (currentBaseState.nameHash + ", " + rollState);
Will output
1094782407, -1476868190
When I'm in the roll state. rollState NEVER = currentBaseState.nameHash.
I did test this with the Idle state, which works perfectly like this :
static int rollState = Animator.StringToHash("Base Layer.Idle");
I can't see what the structure is for sub-states, really frustrating.
Upvotes: 2
Views: 13798
Reputation: 763
In the most up-to-date version of 5.3.4 at time of writing, the question can be partially answered as follows.
First of all, there is no nameHash
any more. The closest variable to it is shortNameHash
. It is recommended to use fullPathHash
instead as will be explained shortly. shortNameHash
is like the bare file name in OS, while fullPathHash
, as its name suggests, contains layer name as path before the state name. Here is an example to use both of them to identify the current state:
int baseState = Animator.StringToHash("Base Layer.Idle");
int short_baseState = Animator.StringToHash("Idle");
int subState = Animator.StringToHash("Base Layer.Jump_Fall_Roll.Roll");
int short_subState = Animator.StringToHash("Roll");
...
AnimatorStateInfo s = myAnimator.GetCurrentAnimatorStateInfo(0);
Debug.Log(s.fullPathHash + ", " + baseState); //they are equal at Idle state in base layer
Debug.Log(s.shortNameHash + ", " + short_baseState); //they are equal at Idle state in base layer
Debug.Log(s.fullPathHash + ", " + subState); //they are equal at Roll state in sub-state machine
Debug.Log(s.shortNameHash + ", " + short_subState); //they are equal at Roll state in sub-state machine
From the above example we can see that shortNameHash
works for bare state name, no matter the state is regular one in base layer, or a state in the sub-state machine. But fullPathHash
works only when layer path is properly prefixed before the state name. If we are sure there is no duplicate state names in different state machines, shortNameHash
is good because it is short, but this assumption does not always hold in a large complex animator controller, so I would like to recommend using fullPathHash
all the time.
I call this answer "partial" because we have to make sure the layer id passed to GetCurrentAnimatorStateInfo is 0, i.e., the "current working layer" (like the pwd
command in linux) should be the base layer. The above path name convention fails if we pass 1 to it. I don't have time to guess what the path name should be in layer 1. Any complement in this regard is welcomed.
Upvotes: 6
Reputation: 2884
I seriously have no Idea what changed in my project, but I tryed
static int rollState = Animator.StringToHash ("Jump_Fall_Roll.Roll");
again (I had tested it before I post this question and spend hours trying to resolve it) and it managed to work..........
So, for Sub-States, do not include the Layer name in the hash, only the parent Sub-State of your State.
I did not test for nested Sub-States.
Thank you to those who tryed to help me
Upvotes: 2
Reputation: 11302
The string to pass in Animator.StringToHash
should include layer's name and state's name.
So to correctly generate the hash it should be:
int rollState = Animator.StringToHash("Base Layer.Roll");
Upvotes: 1