Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Skipping forward without triggering Notifications/AnimationEvents

Discussion in 'Timeline' started by Lost-in-the-Garden, Jul 3, 2020.

  1. Lost-in-the-Garden

    Lost-in-the-Garden

    Joined:
    Nov 18, 2015
    Posts:
    176
    Hello!

    I would like to skip forward in the timeline without triggering all Notifications from markers or Animation Events in Clips inbetween.

    What I am doing right now:

    Code (CSharp):
    1.         private void Jump(double targetTime)
    2.         {
    3.             director.time = targetTime;
    4.         }
    This triggers all notifications that happen between the current time and the targetTime.

    What i have tried so far by looking at other posts here:
    Code (CSharp):
    1.         private void Jump(double targetTime)
    2.         {
    3.             director.playableGraph.GetRootPlayable(0).SetSpeed(0);
    4.             director.Pause();
    5.             director.timeUpdateMode = DirectorUpdateMode.Manual;
    6.             director.time = targetTime;
    7.             director.timeUpdateMode = DirectorUpdateMode.GameTime;
    8.             director.Play();
    9.             director.playableGraph.GetRootPlayable(0).SetSpeed(1);
    10.         }
    And all combinations of the above but none of them help in any way. :(

    Thanks!
    Matthias
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Hmmm.... good question. Getting both events and notifications to not fire can be tricky, their rules aren't quire the same. In particular, you may need to disable the retroactive flag on signals. However, this might work:

    director.time = x;
    director.Evaluate();
    director.Play();

    Evaluating the timeline might be the trick you need, it does have a higher cost. You also might need to call director.Stop() before setting the time.
     
  3. Lost-in-the-Garden

    Lost-in-the-Garden

    Joined:
    Nov 18, 2015
    Posts:
    176
    Hello!

    I am now using this code:
    Code (CSharp):
    1.                             director.Stop();
    2.                             director.time = navigationMarker.time;
    3.                             Log.Debug($"Jumped to {navigationMarker.Tag} at {director.time}");
    4.                             director.Evaluate();
    5.                             director.Play();
    But it still is triggering the animation events inbetween.

    Thanks!
     
  4. bdorris_circadence

    bdorris_circadence

    Joined:
    Dec 11, 2017
    Posts:
    1
    I ran into the same issue. I'm a little surprised your original solution didn't work, I created a function similar to what you have above and it has been working for me. There is one small difference, though. I have found that if the director is currently playing when the time is explicitly set further in the timeline, all of the markers are queued and play in order after the new time is set. My fix was to
    Pause()
    and then
    Resume()
    the director after setting the new time. Here is what I have been using:

    Code (CSharp):
    1. private void SetDirectorTime(double time, bool continueFromNewTime = true)
    2. {
    3.     playableDirector.Pause();
    4.     playableDirector.time = time;
    5.     if (continueFromNewTime)
    6.     {
    7.         playableDirector.Resume();
    8.     }
    9. }
     
  5. Lost-in-the-Garden

    Lost-in-the-Garden

    Joined:
    Nov 18, 2015
    Posts:
    176
    @seant_unity
    I have tried to use Stop & Pause & Evaluate Nothing works. The previous INotifications are always called.
    Also just calling director.Pause() & Resume() calls all INotifications before. This seems like a bug?

    I am at Unity 2019.4

    Or is something wrong with the way I am implementing the INotificationReceiver? (Which is a Monobehaviour attachted to tsame gameobject as the Playabledirector.

    Code (CSharp):
    1.         public void OnNotify(Playable origin, INotification notification, object context)
    2.         {
    3.             if (!Application.isPlaying || TimelineNavigator.JumpInProgress)
    4.             {
    5.                 return;
    6.             }
    7.             if (notification is PauseMarker pauseMarker)
    8.             {
    9.                 Debug.Log("Pause triggered!");
    10.                 director.playableGraph.GetRootPlayable(0).SetSpeed(0);
    11.             }
    12.         }
     
  6. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Are you implementing INotificationOptionProvider on your PauseMarker? If not, the default flags are 'retroactive' which can cause all previous notifications to trigger, as opposed to just markers that have been passed this frame.
     
    Lost-in-the-Garden likes this.
  7. Lost-in-the-Garden

    Lost-in-the-Garden

    Joined:
    Nov 18, 2015
    Posts:
    176
    Yes!

    That was it, I was missing the INotificationOptionProvider interface.

    Thanks!