Cannot restart animation in Mecanim

I need to restart a firing animation if the firing animation is already playing, and the player tries to fire again.

I’m trying to use a null state to restart the animation, but the Fire state check sometimes fail, even though the the state machine is in the Fire state, resulting in the “isRestarting” variable not to be set to true.

How should this be implemented?

void FixedUpdate()
{
	...
	// Aiming
	anim.SetBool("isAiming", weaponColtroller.IsAiming);

	// Shooting
	if (isFiring) // isFiring is set to true by an event that is triggered when the player clicks the mouse
	{
		isFiring = false;
		
		if (anim.GetCurrentAnimatorStateInfo(1).nameHash == Animator.StringToHash("Aiming Firing Layer.Fire")) // NOT WORKING
		{
			anim.SetBool("isRestarting", true);
			Debug.Log("DOUBLE TAP");
		}
		anim.SetBool("isFiring", true);
	}


	if (anim.GetCurrentAnimatorStateInfo(1).nameHash == Animator.StringToHash("Aiming Firing Layer.Null"))
	{
		anim.SetBool ("isRestarting", false);
	}
	if (anim.GetCurrentAnimatorStateInfo(1).nameHash == Animator.StringToHash("Aiming Firing Layer.Fire"))
	{
		anim.SetBool ("isFiring", false);
	}
	...
}

The state machine:

  • Aim → Fire when isFiring is true.
  • Fire → Aim when isRestarting is
    false and on exit time.
  • Fire → Null when isRestarting is
    true. Instant.
  • Null → Fire when isRestarting is
    false. Instant.

12123-statemachine.png

Here’s how I would do it: Don’t even have a Null state. Make it so that isFiring turns true when you tap the button, but turns false RIGHT AWAY; you could make it so if isFiring is true, Is Firing turns False. That would give even an instant of isFiring true, which would activate the animation. For the exit clause of the firing animation, just put it to exit time. This should make it so that if you tap ‘fire’, the animation will always restart. So basically, your code is pretty good but change a those things in the state machine.

Another way of handling this is to make 2 firing animations: one long one for the beginning and end, and one really short one for if you fire multiple times so that the animation finishes and restarts quickly.

dunno, but now you can do just:

Animator.Play(state, layer, normalizedTime);

if you use

Animator.Play("same state you are", -1, 0f);

it will restart current state, if you put whatever float from 0 to 1 into normalized time, you can set it to any time position you want

you can also use

Animator.CrossFade(state, crossFadeTime, layer, normalizedTime);