Mecanim Trigger getting stuck in 'TRUE' state

So,
I have some triggers in the Animation Controller - these work fine most of the time… I call SetTrigger() from the code and they trigger once and then are immediately false - waiting to be triggered again.
But occasionally i notice that the anim is auto-happening when it should be waiting for the trigger. When i check in the Animation Controller I can see a little tick next to the trigger indicating it’s constantly turned on… behaving like a ‘bool’ - …
this seems to be a Unity bug… anybody got any ideas ?
Thanks

Ultroman’s answer is not 100% exact. The problem does not (always) occur when you trigger an animation that is currently being played. It does occur when you trigger an amination while a transition is still running.

Let’s say you have 2 animations: A and B and 2 triggers: tA and tB, animation A plays when tA gets triggered and animation B plays when tB gets triggered. If you trigger tA animation A will start playing, but if you trigger tB before animation A has finished, tA won’t be reset, it will remain true until animation A is played from begining to end. The same also happens if you trigger tA for a second time while animation A is still playing.

So, if for some reason you need to trigger tB and you are not sure if animation A has finished, you should use ResetTrigger, I didn’t understand why the guys at Unity decided to include this funtion until I stumbled upon this problem.

To prevent this unwanted behaviour you should do something like this:

animator.ResetTrigger("tA");
animator.SetTigger("tB);

2021 update: Check out the answer by georgeq above instead or follow this link: Mecanim Trigger getting stuck in 'TRUE' state - Unity Answers


ORIGINAL ANSWER:
I found out that there is a problem with Mechanim, if you try to trigger the same animation that is already running. I don’t think it is built for that. It is a state-machine after all, so it makes sense that it should never trigger an animation that is already running.

You “simply” have to check if the animation you’re starting is already running.

I’ve done these steps to ease my life:

  1. Made one trigger for each of my animations, with the same name as the animation I want to trigger! (this is important, if you want to use the simple functions below)

  2. Made a transition from “Any State” to each of my animations, and the only condition for each transition, is the matching trigger.

  3. Then I made a PlayAnimation function, which checks if the animation is already running:

.

public void PlayAnimation(string animationName){
    if (!_animator.GetCurrentAnimatorStateInfo(0).IsName(animationName))
        _animator.SetTrigger(animationName);
}

…and here’s one where you can control the layer you’re checking:

public void PlayAnimation(string animationName, int layer){
    if (!_animator.GetCurrentAnimatorStateInfo(layer).IsName(animationName))
        _animator.SetTrigger(animationName);
}

The IsName() function checks if the string you pass it, is the name of the currently playing animation. If it isn’t, I use the trigger with the same name. Simple.

This works for me.

The animations trigger instantly, though.

I don’t know if this interrupts non-atomic animations.

EDIT:
Since doing this, I somehow got my Animator working normally, so now I can just do:

_animator.Play(animationName);

It doesn’t screw up anymore, and I don’t need to use triggers at all.
And also, I can do this to restart the running animation from scratch, even if it is the same animation:

_animator.Play(animationName, layer, 0.0f);

I don’t know why, but this wasn’t working yesterday. _animator.Play() just didn’t do anything.

This is how I did in my game after reading the articles.

string currentAnimation = null;

void setAnimation(string stringInput){
	Animator anim =transform.GetComponent<Animator>();
	Debug.Log("Setting Anim to : " + stringInput);
	if(currentAnimation==stringInput){

	}else{
		if(currentAnimation!=null){
			anim.ResetTrigger(currentAnimation);
		}
		anim.SetTrigger(stringInput);
		currentAnimation=stringInput;
	}
}

you need to turn on flag “can transition to self” in transition settings rollout.

For what it’s worth, I’ve had this problem when setting the trigger while in a state that had no exit condition based on that trigger. The trigger was simply not consumed.

Try this. It helped me with both problems.

animator controller > click on state > uncheck “write defaults”

I did this to all states in my animation controller. It worked for me.

As far as I understand a Trigger is represented as a boolean internally. If the Trigger is fired, the boolean is set to true. As soon as the transition enters, the boolean is set to false.
If, for any reason, the transition is not entered, the boolean/Trigger will remain true. The first time the transition is checked again, the Trigger is still true and will fire, checking the transition and setting itself to false.

A common scenario:
You have a Grounded, Jumping and Airborne state and 2 parameters: a boolean isGrounded and a Trigger Jump. The transition from Grounded to jump requires the Jump Trigger to be triggered, from Grounded to Airborne the IsGrounded boolean to be false and from Airborne to Grounded the IsGrounded boolean to be true.
When you jump, you trigger the Jump Trigger and you also set IsGrounded to false. When you fall from a platform, you only set IsGrounded to false.

What can happen when you jump (by triggering the Jump Trigger but also setting IsGrounded to false) is that both transitions from Grounded to the Jump and to the Airborne state fulfill their conditions. When the Aiborne state is chosen, the Jump Trigger will remain true (since the transition to Jump is not entered). When you land on the ground again and IsGrounded is set to true, the Airborne state transitions to the Grounded state. Because the Jump Trigger is still set to true, the Grounded state immediately transitions to the Jump state and sets the trigger to false.

The above example can simply be fixed by setting the priority of the transition to Jump higher than the transition to Airborne (by selecting the Grounded state and dragging and dropping the transition to Jump above the transition to Airborne). In a more general case, be sure when multiple transitions could happen and either change their priority, set the Trigger to false explicitly in code or rethink the design.

Some good answers here, but ultimately the issue is you might have to force Animator.ResetTrigger in some situations. Here is a code snippet that will let you do a reset from an Animator state so you don’t have to write any extra code. To apply it click your animator state you want to trigger the reset → In the inspector click Add Behavior → Add the ResetTrigger script. This is a best practice since it confines your Animator logic instead of letting it wander around your scripts. Making it very easy to go back and remove this from the Animator later if you want to.

    public class ResetTrigger : StateMachineBehaviour {
        [Tooltip("The trigger you wish to reset")]
        [SerializeField]
        private string _trigger;

        private void OnStateEnter (Animator animator, AnimatorStateInfo animatorStateInfo, int layerIndex) {
            animator.ResetTrigger(_trigger);
        }
    }