Search Unity

Animator.Update(0) firing events in Unity 5.6

Discussion in 'Animation' started by DDNA, Apr 25, 2017.

  1. DDNA

    DDNA

    Joined:
    Oct 15, 2013
    Posts:
    116
    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?
     
  2. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    bump...
     
  3. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    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.
     
  4. DDNA

    DDNA

    Joined:
    Oct 15, 2013
    Posts:
    116
    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
     
  5. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    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
     
  6. daxiongmao

    daxiongmao

    Joined:
    Feb 2, 2016
    Posts:
    412
    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.
     
  7. DDNA

    DDNA

    Joined:
    Oct 15, 2013
    Posts:
    116
    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
     
  8. DDNA

    DDNA

    Joined:
    Oct 15, 2013
    Posts:
    116
    I just reproed this and reported it in a completely trival test case.
     
  9. DDNA

    DDNA

    Joined:
    Oct 15, 2013
    Posts:
    116
    Case 938978
     
    Mecanim-Dev likes this.