- Home /
Mecanim bool parameter is staying true for too long
I made a simple gun with a simple shoot animation. I'm using the mecanim animation system to handle the animation. I have dragged an idle animation to the window, which is the default state, and I dragged the shooting animation. The transition from idle to shoot happens when a bool parameter called "Shot" is set to true.
My problem is that Shot stays true for too long and my shooting animation is 4 frames long. As a result, my shooting animation loops 3 times. I tried handling the parameter like in the mecanim tutorial, but it didn't help. I tried making the bool parameter false immediately after making it true, but then it doesn't play at all.
EDIT: I uploaded the project file here(it's really small): https://www.dropbox.com/sh/4r98vv5hyaeyzzk/PQTHWxA9hV
This is what my code looks like currently:
private Animator anim;
static int shootState = Animator.StringToHash("Base Layer.Shoot");
private AnimatorStateInfo currentBaseState;
void Start () {
anim = gameObject.GetComponent<Animator>();
}
private bool canShoot = true;
void Update () {
currentBaseState = anim.GetCurrentAnimatorStateInfo(0);
if(Input.GetButtonDown("Fire1"))
{
if(canShoot)
{
canShoot = false;
anim.SetBool("Shot",true);
}
}
else if(currentBaseState.nameHash == shootState)
{
anim.SetBool("Shot",false);
}
else
{
canShoot = true;
}
}
Answer by TrickyHandz · Sep 28, 2013 at 04:23 PM
You should be doing the comparison of the base state of the animator prior to checking for input. That way all your bools can be reset at the beginning of the frame and input can be checked afterwards. Currently, you are checking input first, which could potentially be causing the looping effect you are experience. Here is an example to try:
private Animator anim;
private bool canShoot;
// Animator states to track
static int shootState = Animator.StringToHash("Base Layer.Shoot");
static int idleState = Animator.StringToHash("Base Layer.Idle");
private AnimatorStateInfo currentBaseState;
void Start ()
{
anim = gameObject.GetComponent<Animator>();
canShoot = true;
}
void Update ()
{
// Get the current base state of the animator
currentBaseState = anim.GetCurrentAnimatorStateInfo(0);
// Check to see if we are in the shootState.
// If so, the transition was obviously triggered
// and the bool should be reset immediately
if(currentBaseState.nameHash == shootState)
{
anim.SetBool("Shoot", false);
canShoot = true;
Debug.Log("All booleans reset");
}
// Now we check that the animator is in
// the idle state
if(currentBaseState.nameHash == idleState)
{
Debug.Log("Animator in Idle. Player can shoot");
// Now we can check for inputs and do our
// check against canShoot that will alter
// the animator state. If the player hits
// "Fire1" and canShoot is true, set canShoot
if(Input.GetButtonDown("Fire1") && canShoot)
{
canShoot = false;
anim.SetBool("Shot",true);
Debug.Log("You fired a shot.");
}
// Just for good measure we can set our
// bools back to default values, though
// this "else" statement, shouldn't be
// necessary. You can try it with or
// without the following code.
else
{
canShoot = true;
anim.SetBool("Shot", false);
Debug.Log("Redundant Check: Booleans reset");
}
}
}
Hope that helps you out. Let me know if the comments don't make sense. Also, you could consider doing the input check on FixedUpdate() rather than Update() as well. If you want an example of that, let me know and I will edit accordingly.
EDIT:
"Exit Time" in the animators transition back to idle will not cause the animation to loop. When importing the animation make sure that the "Loop Pose" setting in "Animation Tab" of the corresponding model is not checked. Having this checked will cause the animation to loop until the transition is completed rather than running only once. Here is a link to the project with the correction in it: Shooting Animation Loop - fixed
Thank you very much for your answer. Unfortunately while this fixed the shot boolean only reverting back to false after 3 seconds, the animation still loops three times.
The boolean paremeter turns to false almost immediately after the animation starts, yet the animation still loops three times before ending. I guess the bool staying true for too long wasn't actually the problem, but if I don't get any more answers I'll accept yours since technically you answered the question.
EDIT: Could it have something to do with the transition back to idle? Here's a screenshot of the settings for the transitioning back to idle: http://i.imgur.com/IBGhXQR.png?1?8977
@Paparakas, I would recommend trying to shorten the exit time. Try setting it to 0.01 and that should give you a nearly instantaneous transition out when the animation is done, ins$$anonymous$$d of mecanim trying to blend it out. Let me know if that fixes it and I will add it to notes in my answer for the sake of completeness.
@TrickyHandz :( Doesn't work. Still loops three times. This sucks :(
@TrickyHandz I uploaded a small project with the problem in question. Just in case you might want to look at it: https://www.dropbox.com/sh/4r98vv5hyaeyzzk/PQTHWxA9hV
@Paparakas, the issue does in fact exist in the import settings for the pistol that has the shoot animation on it. "Loop Pose" was checked for that animation and I unchecked it and everything seems to be working fine now. Here is a link to the a zipped version of the project with the fix in it: Project with Fix
Let me know if you still have issues with it. I'm editing my answer above to include the additional information we discussed.
Answer by TonyLi · Sep 28, 2013 at 02:10 PM
You have to make it false after the transition has triggered, which is why setting it to false immediately didn't work.
Try adding some Debug.Log lines. Are you sure that the state name is correct? Is it ever getting to the animSetBool("Shot",false); line?
Thank you for your answer! I imagined that was the reason setting it immediately didn't work, since if it detects that it was set to false during the transition it reverts back.
I'm positive that the state name is correct, here's the animator window: http://i.imgur.com/nLEfGxk.png?1
Also, I added some debug lines and it does get set to false. The only reason I already knew that is because I can clearly see the Shot parameter in the animator window taking like 3 seconds before it gets set to false. Which is enough time for the shooting animation to loop 3 times.
Shot in the dark here...the animation isn't set to loop in the import settings is it?
@TrickyHandz No, I disabled loop pose. If I have it enabled it visibly loops three times. If I keep it disabled it loops three times but I only see the animation play once. Would make it fine if it wasn't for the fact that I can't replay the animation while it's busy looping.