[Animator] Don't use SetBool (string name) with string parameter !

Hello

After little experiment I have found that it is forbidden to use SetBool (or any other Set in Animator, like SetTrigger, SetFloat) with input parameter string name.

Use SetBool (int id) , if you want to get maximum performance.
According to my tests, SetTrigger with string is 2x slower than with ID !

Performance tests:
Call count: 1 000 000 000.

  1. SetTrigger (string name) - 1:52 (min, sec)
  2. SetTrigger (int id) - 0:55 (min, sec)
  3. StringToHash (string name) - 1:18 (min, sec) - just to test speed of this function. You need to call it only once and save the returned id.

What is that id ? How do I get it ?
This is not index of your parameter in the Animator window.
To get id you need to call Animator.StringToHash(string name) at Start or Awake (just only once), where name is name of parameter which you used in SetBool(string name). StringToHash returns ID, as integer.

Anyways, one call of SetBool (string name) will be absolutely not a big task, but ‘int id’ will be faster :slight_smile:

Thanks.

14 Likes

good tip thanks this will save a few ms or ns thanks !

2 Likes

Thank you.
I am making different performance tests fairly often, so I decided to start publishing them to the forum.
Watch for my topics, I’ll upload something else during the current week.

2 Likes

maybe try just compiling a list here rather then posting a new topic each time , also thanks for taking the time to do this.

Note that there is a very small chance of getting a collision with using the hash. In other words two strings used for a trigger could result in the same hash value.

yes this and some other tricks (like CompareTag) are discussed here, rider can do them for you, shame it’s 140 us a month!..

1 Like

Thanks for measuring the time.

I wish we could simply use a reference and no string at all.

2 Likes

You can avoid Animator Controllers and Magic Strings and just directly reference the AnimationClips you want to play if you use Animancer (link in my signature).

But if you are going to keep using Animator Controllers, don’t call StringToHash in Start or Awake like OP suggested, call it in a static field initialiser so that it only has to run once when that script type is initialised instead of once for every instance of the script:

public static readonly int MyBool = Animator.StringToHash("MyBool");
3 Likes

is readonly fast, like public static final in java?

I believe it can be very slightly faster in some cases, but the main reason to use it is to ensure that nothing else accidentally reassigns the value and breaks your animation code.

1 Like

thanks I implemented the fix, every npc used to do it!

Note that I was referring to readonly being slightly faster.

Making them static and only doing the hash calculation once will be much faster.

2 Likes

I use static readonly int to set the character falling state to “true” => animator.SetBool(Fall, _character.IsFalling()); which works fine, but I can’t set the int ID to “false”. animator.SetBool(Fall, false); is not disabling it. Can you advice what should be done to set it as “false”?

That would do it so your problem must be elsewhere. Maybe your code isn’t running that line or you have multiple copies of the script or character in the scene and you’re looking at the wrong one.

No it isn’t - you’re out by a factor of 12.

yeh not sure why I said that, 140us a yr is still too much though, it comes around fast :slight_smile: