How to get Playable.GetTime() when not in play mode ?

Hi,

I'm trying to retrieve the current time of a Playable inside a PlayableBehavior ProcessFrame method but the method return 0 when not in playing mode. What I want is to know the progression (value from 0 to 1) inside the clip.

With that thread I was able to retrieve the start and end properties : https://discussions.unity.com/t/676487

Now I need to retrieve the current time in order to compute a normalized value which will represent the progression inside the clip. GetTime will work but only in play mode.

Any idea ?

Thanks

public override void ProcessFrame(Playable playable, FrameData info, object userData)
{
     Debug.Log(playable.GetTime());
}

When used on a playable behaviour for a clip the above code always shows the clip time, in editor or playmode. When used on a mixer behaviour, i.e. for a track, it is not a reliable source in editor because the track playable time is never explictly set. It starts at 0 and advances in playmode, but is never reset for loops or if you scrub. In the editor, it's time never advances because the playback is only simulated.

If you are looking to get the time of the timeline, you can use playable.GetGraph().GetRootPlayable(0).GetTime().
The timeline playable is the (only) root of the graph, and it's time is what is displayed by the timeline playhead.

Ok.

Question, in which order ProcessFrame is called in playable behavior and the mixer behavior ?

Another question : Is there a way (an easy and intuitive way) to know for each clip ( playable behavior) the current progress ? Let's say I have a clip that start at 0 and end at 100. When the global time is at 75 the clip (playable behavior) progress should be 0.75. It would be nice and useful to get data like this. So far I have the feeling that nothing is easy with Timeline. There is always a trick but nothing really intuitive and simple - it's really frustrating.

Thanks

PrepareFrame is called 'top-down' - it is called on the mixer prior to it being called on any active clips.

ProcessFrame is called 'bottom-up' - it is called on the clips prior to it being called on the mixer.

To get the normalized time, in the clip's playable behaviour, you can call playable.GetTime()/playable.GetDuration(), depending on the functionality of your clip (clip-in and playableAsset.duration can change the meaning of that).

As for the frustrating part of writing playables in timeline, that's a pain point that we understand. Extending timeline is done through using the Playable API - not a timeline specific API. We have design drafts for creating timeline specific classes (e.g. TimelineBehaviour instead of PlayableBehaviour) to make extending timeline more intuitive, and address that frustration.

1 Like

Thanks !

Is there a way to either get the FRAME number of the playhead relative to the clip or the artist's set frame rate in order to calculate it ourself?

Not directly, the playable system doesn't work in frames, everything works in seconds. You can get the playhead time by using

playable.GetGraph().GetRootPlayable(0).GetTime().

The frame rate is stored inside the timeline asset as timelineAsset.editorSettings.fps; That's not accessible directly from a playable behaviour, but you can set it on a custom behaviour when you create one.

class MyPlayableAsset {
    ....
    public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
    {
        var playable = ScriptPlayable<MyBehaviour>.Create(graph);
        var playableDirector = go.GetComponent<PlayableDirector>();
        if (playableDirector != null)
        {
            var timelineAsset = playableDirector.playableAsset as TimelineAsset;
            if (timelineAsset != null)
                playable.GetBehaviour().frameRate = timelineAsset.editorSettings.fps;       
        }
        return playable;
    }
    ...
}

Works perfect thanks!

[quote=“seant_unity”, post:4, topic: 677426]
PrepareFrame is called ‘top-down’ - it is called on the mixer prior to it being called on any active clips.

ProcessFrame is called ‘bottom-up’ - it is called on the clips prior to it being called on the mixer.

To get the normalized time, in the clip’s playable behaviour, you can call playable.GetTime()/playable.GetDuration(), depending on the functionality of your clip (clip-in and playableAsset.duration can change the meaning of that).

As for the frustrating part of writing playables in timeline, that’s a pain point that we understand. Extending timeline is done through using the Playable API - not a timeline specific API. We have design drafts for creating timeline specific classes (e.g. TimelineBehaviour instead of PlayableBehaviour) to make extending timeline more intuitive, and address that frustration.
[/quote]

hi, seant
I made a small demo and found out that ProcessFrame is also called ‘top-down’, instead of ‘bottom-up’.

3991396–343537–TestTimeline.zip (49.5 KB)

Yes, that's a bug we intend to fix :)