Animator.Update(0) firing events in Unity 5.6

So starting with 5.6 Unity seems to be firing events when Update(0) is called. Then when the animation plays you get the event again. So the result is if you have an Event on the first frame of an animation you get it called twice.

Calling Update(0) is a necessity because certain things need to happen after unity state change is completed. For example there is some code to switch states that needs to keep animation speeds correct.

Animator.SetFloat(_speedParmID, (float)1);
Animator.CrossFadeInFixedTime((int)animHash, (float)fixedBlendTime, AnimLayer);
Animator.Update(0);
Animator.SetFloat(_speedParmID, (float)speed);

If the speed variable isn’t set before the call the transitions don’t happen at the right speed. Mechanim has a general problem where when you set something in the API you can’t read it immediately back until the Update is run. i.e. one place in your code tells mechanim to play something, then another asks it what it is playing. If a frame hasn’t happened before the ask, you will get incorrect animation. For this reason I find myself calling Update(0) a lot.

I tried turning these all to Update(.001) but despite this it triggers the event again on the next frame. Is this expected behavior? Is there a way to disable events on the animator?

bump…

Hi DDNA,

no it not an expected behaviour, it shoudln’t fire any events if the time doesn’t advance. Could you log a bug please, we will investigate what is going on

animator.fireEvents = false;
this is mainly for tools when you don’t want to fire events like by example when we play an animation in the animation windows.

If I have an event at 0. Then I set this flag to false. Then do the Update(0) and then set the flag to true will I lose the event completely

I think so
AnimationEvents fire rule are as follow

When starting a new state the range is
]currentTime-epsilon, currentTime]
on all subsequent frame the range is
]previousTime, currentTime]
and if previousTime == currentTime → No events fired, game could be paused

So in your case since you do an Update(0), previousTime == currentTime so it shouldn’t fire any events

From what you said if his first frame after calling a new animation to play is currentTime-epsilon, currentTime.
Wouldn’t that make previous time = 0 - epsilon.
And current time = 0. and then update(0) the test would fail and fire event.
Since this is the very first update call.

Previous time is now set to current time which is 0. Unity ticks next frame and you have
0, t. So they are not equal and the event would be fired.

Ha. A lot to read into 4 lines of some pseudo code.

This is still happening for us, and it is causing all sorts of problems. If the event is at 0, then we get it on Update(0) and then again on the next frame. This only started happening in 5.6 ans is still happening in 2017.1p2

What we have to do is move every event to some small epsilon like t=0.01

I just reproed this and reported it in a completely trival test case.

Case 938978

1 Like