- Home /
possible bug with animator.speed and triggers
Hi,
I'm experiencing some hard issue with unity and my NPC are sometimes not animated how they should. I first thought it was some problem in my code (which I won't post since it's pretty much big and complex) but after some (a lot of) time I figured that it was somehow linked to the animator.speed, which I am using to blend the moving animations. When I don't change the animator.speed, the triggers works perfectly but if I play with it and it comes under a certain limit (which I didn't figured yet), the triggers are not or badly received and of course my animations are totatlly messed up.
This seems like a bug in unity for me but maybe it's somehow intended? Is this known? Is there a workaround i should use? I didn't tried the blend trees yet because I didn't needed it but maybe it could actually solve my issue?
EDIT: actually the triggers works bad sometimes even if i don't play with speed, so there are bugs in my scripts but it's still somehow linked as the more i lower the animation.speed limit the more i see the problem occuring.
Answer by barbe63 · Jan 03, 2015 at 11:02 AM
I will try to more specific and put a piece of my code to explain my problem better
It's a function that make my NPC stop and look for the player if it is getting close (triggered by a noise collider)
IEnumerator LookBehind(GameObject source)
{
isLookingBehind = true;
/*boolean to stop the coroutine if it's running, is set to false
in another function which is using StopCoroutine*/
debugTBstopped=true;
/* this is only for debugger purpose, if it's false in the debugger
it means that the last time it ran it wasnt stopped by a StopCoroutine.*/
anim.SetTrigger("turnBack");
// the only place in my code where this trigger is called
float lookingTime = 2.5f;
while (!isAfraid && lookingTime > 0 && !isRagdoll)
{
// basicly a lookat player
Vector3 sourceDir = player.transform.position - trans.position;
Quaternion rotation = Quaternion.LookRotation(sourceDir);
rotation.x=0;
rotation.z=0;
trans.rotation = Quaternion.Lerp(trans.rotation, rotation, Time.deltaTime * 2);
lookingTime -= Time.deltaTime;
yield return null;
}
if (!isDead && !isGlued && !isRagdoll)
{
try
{
agent.enabled = true; //set the navmeshagent on again
onHisWay = false; // false means it will set a new destination
}
catch
{
print("Error trying to set Agent on");
}
isStopped = false;
if(!isAfraid) //if it hasn't see the player resume walk
anim.SetTrigger("resumeWalk");
GetComponentInChildren<Sight>().isLooking=false;
//telling to the sight component that it have finish to look for the player
}
debugTBstopped=false;
isLookingBehind=false;
}
For the record the argument source is never used yet as for now it only search the player, later it will search for any sound position.
So the problem is in rare occasion the NPC is stucked on the "turnBack" animation while it should do the resume walk. Actually it does the resume walk and after 1s it returns on turnBack state and stick on it. The strangest part is in the debugger i can see that the coroutine is not running (isLookingBehind = false) and last time it ran it has finished the coroutine entirely (debugTBstopped = false). isDead, isGlued, isRagdoll and isAfraid = false so the trigger resume walk should have been triggered. Those value can't possibly be true at any part of my code when I meet the problem. (The NPC is obviously not dead, not glued haven't been in ragdoll state or seen the player once) In the animator the only way to go in the turnBack is with the trigger.
Can someone can please tell me what is going on then? I know this is only a part of my code and the problem can be elsewhere but as i stated this is the only place where the trigger is called, and the booleans seems to state that my problem can't occur then but it still does.
And to complete my explanation here is my StopCoroutine function
if(isLookingBehind)
{
StopCoroutine("LookBehind");
if(!isStopped && !isDead)
{
if(!isAfraid)
anim.SetTrigger("resumeWalk");
else
anim.SetTrigger("run");
}
isLookingBehind=false;
}
and the AnimSpeed()
if (isLookingBehind)
{
float rotationSpeed=0f;
if(trans.eulerAngles.y != lastOrientation)
{
rotationSpeed = Mathf.Abs(lastOrientation-trans.eulerAngles.y)/3.53f;
//3.53 = numbers of degrees per frame to achieve a 180 degrees rotation
}
lastOrientation = trans.eulerAngles.y;
anim.speed = Mathf.Max(0.68f * rotationSpeed, animSpeedMin);
//0.68 = the base animation speed, can't remember exactly how i calculated that
}
So the thing is the problem seems to occurs more if animSpeedMin is equal to 0, so my weird theory was as the animator speed was on 0 on some rare occasion it would not record the trigger properly. But it seems i'm wrong on this since it happens even if animSpeedMin = 1. The last explanation i can see is some "XFiles bug". I name this the bugs that are in a total different place for a different purpose and curiously mess up something unrelated directly. I hope not because it would be really hard to identify then. Maybe you see some other explanation?
EDIT: anyway they are definitly major bugs in my unity. When sometimes for no reason it keeps bugging on an event for a supposed clone of my NPC(not existing) that doesn't have a navmesh agent attached and i need to relaunch Unity for the bug disappear, I call this unity bug. When after relaunch some of my transitions in animator just disapeared, i don't take much risks calling this a Unity bug.
EDIT 2: i temporary add a fix to my AnimSpeed() function that should avoid the problem that can occur with eulerangles when one if under 360 and the other over 0 by just adding this.
if (Mathf.Abs(lastOrientation-trans.eulerAngles.y) >180f)
rotationSpeed = 360-Mathf.Abs(lastOrientation-trans.eulerAngles.y)/3.53f;
Still bugging the same way... I also forgot to mention that if i remove the call for the Coroutine it seems no more problem are occuring with any other animations so it really looks like the problem is localised on those codes...
EDIT 3 :
It looks like i finally fixed my issue!!
So for those who are interested that was a combination of 3 steps: First i noticed that my problem didn't happen anymore if i removed the AnimSpeed function from the update.
So 1) I changed this:
if (Mathf.Abs(lastOrientation-trans.eulerAngles.y) >180f)
rotationSpeed = 360-Mathf.Abs(lastOrientation-trans.eulerAngles.y)/3.53f;
to this (forgot some parentheses... oops)
if (Mathf.Abs(lastOrientation-trans.eulerAngles.y) >180f)
rotationSpeed = (360-Mathf.Abs(lastOrientation-trans.eulerAngles.y))/3.53f;
The animator.speed was sometimes exceding 200! So yeah that seems to mess up things...
2) I needed also to set animSpeedMin to higher than 0, i set it to 0.3. So low speed also seems to mess up triggers on some occasions.
3) I tried to remove the atomic check for the transition between my walk and turnback... That was making the same bugs so i checked it again.
I'm glad that seems to be fixed (crossing fingers) but i still wonder if that can't be called a unity bug.
Your answer
Follow this Question
Related Questions
Animations not transitioning properly 1 Answer
Mecanim issue: Twitching when blending into blendtrees 1 Answer
Mecanim CrossFade transition interruption issue 3 Answers
How do I pass a parameter for trigger animations in the animator controller unity 5 file 0 Answers
How to trigger animaton on two different Game Object's at the same time? 1 Answer