How to Properly Pause or Hold at the End of a Timeline Clip

Hi!

Asking to see if there’s a good way to pause/hold on clip end?
I’ll use “stop” as i have pause option and hold option made, speed etc, that’s not the issue.

Currently I have not really figured out a “nice” way to stop on the clip end.
If i use PrepareFrame/ProcessFrame, i have to account for the last call to that method being 1-2 frames to early, if i use OnBehaviourPause, which is called 1 frame after, enabling other clips with is not desired.

Sure i can get around the last frame in the Frames methods being 1-2 frames too early, and Evaluate the last frame manually, but i wanted to ask and see it there’s a better way that i have not found.

Thanks!

After a lot of searching i found this older post

This yielded the best result so far, then me trying to do math, as the frames are not consistent for that. likely due to unscaledTime. Now i need to figure out why the code refuses to restore the edited timeline after playmode exists… but this question i mark as solved, which it is for me.

If anyone wanna give some tips or so, feel free.

Sharing some code incase someone googles this post.

// Variables to keep in mind
defaultTime = timelineAsset.duration; 
defaultDurationMode = timelineAsset.durationMode;
timelineAsset.durationMode = TimelineAsset.DurationMode.FixedLength;

public override void OnBehaviourPlay(Playable playable, FrameData info)
{
    if (!Application.isPlaying) return;

    director.extrapolationMode = wrapMode;
    timelineAsset.fixedDuration = cachedClip.end;
}

public override void OnBehaviourPause(Playable playable, FrameData info)
{
     if (!Application.isPlaying) return;

     // was exited unnaturally, meaning something else influenced this clip not to reach the end.
     if (info.evaluationType == FrameData.EvaluationType.Evaluate)
         return;

     switch (wrapMode)
     {
         case DirectorWrapMode.Loop:
             ReturnToClipStart();
             break;
         case DirectorWrapMode.None:
             RestoreTimeline();
             break;
         default:
             break;
     }
}

    void ReturnToClipStart()
    {
        if (director == null || cachedClip == null) return;

        director.time = cachedClip.start;
        director.Evaluate();

        if (!director.playableGraph.IsPlaying())
            director.Play();
    }