- Home /
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.
No. It only comes sometimes. It seems that during a transition multiple versions of FixedUpdate run. For instance, during the transition from Aim to Fire, there's one version for the Aim state and one for the Fire state. If I happen to get the version for the Aim state when setting isFiring to false, then checking for the Fire state fails, and the isRestarting property is not set to true. Then when the version of FixedUpdate for the fire state comes along, isFiring is already set to false, and line 9-17 is skipped, also not setting isRestarting to true.
Answer by TonyLi · Jun 18, 2013 at 03:13 PM
It just occurred to me that a transition from Any State might be easier. You could just transition from Any State --> Fire whenever isRestarting is true. Then, whenever the current state is Fire, set isRestarting back to false.
I'll look over the code also and let you know if anything pops out at me.
In this scenario, where do I set isRestarting to true? Because that really the one causing the trouble.
I suppose you don't even need isRestarting. You'd just need these states and transitions:
Nothing <--> Aim
Any State --> Fire --> Aim
Whenever the parameter isFiring is true, it will trigger the Any State --> Fire transition -- even when you're already in the Fire state, for your double-tap.
You'd just need that last if statement to reset isFiring:
if (anim.GetCurrentAnimatorStateInfo(1).nameHash == Animator.StringToHash("Ai$$anonymous$$g Firing Layer.Fire")) {
anim.SetBool ("isFiring", false);
}
This works much better, but not completely. If I don't have the transition back to aim, the firing animation will reset everytime I press the fire button, but then it of course get stuck in Fire. The transition to Aim breaks it somehow. What exactly should the properties for the transition from Fire to Aim be? I'm not sure why Aim is blocking Fire from playing again.
$$anonymous$$aybe it's blocking during the transition from Fire to Aim. $$anonymous$$ake sure Atomic is unticked on the transition. (If a transition is atomic, it can't be interrupted.)
Answer by Hyperion · Jun 18, 2013 at 08:49 PM
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.
Answer by komodor · Jan 24, 2014 at 12:14 AM
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);
You have posted this in a few places.
But, I must ask, how can a layer possibly have a value of -1?
I was under the impression they start at 0 for base layer and go up from there.