Search Unity

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

Discussion in 'Timeline' started by Kiupe, Sep 18, 2017.

  1. Kiupe

    Kiupe

    Joined:
    Feb 1, 2013
    Posts:
    528
    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://forum.unity.com/threads/how...d-time-in-playablebehaviour-functions.494344/

    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
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Code (CSharp):
    1. public override void ProcessFrame(Playable playable, FrameData info, object userData)
    2. {
    3.      Debug.Log(playable.GetTime());
    4. }
    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.
     
  3. Kiupe

    Kiupe

    Joined:
    Feb 1, 2013
    Posts:
    528
    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
     
  4. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    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.
     
    forestrf likes this.
  5. Kiupe

    Kiupe

    Joined:
    Feb 1, 2013
    Posts:
    528
    Thanks !
     
  6. jwvanderbeck

    jwvanderbeck

    Joined:
    Dec 4, 2014
    Posts:
    825
    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?
     
  7. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    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.

    Code (CSharp):
    1. class MyPlayableAsset {
    2.     ....
    3.     public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
    4.     {
    5.         var playable = ScriptPlayable<MyBehaviour>.Create(graph);
    6.         var playableDirector = go.GetComponent<PlayableDirector>();
    7.         if (playableDirector != null)
    8.         {
    9.             var timelineAsset = playableDirector.playableAsset as TimelineAsset;
    10.             if (timelineAsset != null)
    11.                 playable.GetBehaviour().frameRate = timelineAsset.editorSettings.fps;      
    12.         }
    13.         return playable;
    14.     }
    15.     ...
    16. }
     
  8. jwvanderbeck

    jwvanderbeck

    Joined:
    Dec 4, 2014
    Posts:
    825
    Works perfect thanks!
     
  9. GuoQing

    GuoQing

    Joined:
    Jun 17, 2013
    Posts:
    1
    hi, seant
    I made a small demo and found out that ProcessFrame is also called 'top-down', instead of 'bottom-up'.
     

    Attached Files:

  10. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Yes, that's a bug we intend to fix :)