Timeline set Time

Hi i want to set the played frame - the "time" of the timeline manually -

as far i can control the slider in the timeline by using this code but the frame doesnt update correctly
timeline update method gametime, play on awake is false

hope you can help me

public void setTime() { // gets called by my scrollbar

        Scrollbar Scrollbar = scroll.GetComponent<Scrollbar>();
        PlayableDirector playableDirector = GetComponent<PlayableDirector>();

        float maxtime = 1;

        playableDirector.time = Scrollbar.value * maxtime;
    }
1 Like

Still looking for answers :( - or isnt it possible?

playableDirector.Evaluate() is what your are looking for I believe.

2 Likes

thank you for the answer: for other readers - my final solution was

private void setTime() {
      
        Scrollbar Scrollbar = scroll.GetComponent<Scrollbar>();
        PlayableDirector playableDirector = GetComponent<PlayableDirector>();

        Debug.Log(Scrollbar.value);
        float maxtime = 1;

        actTime = Scrollbar.value * maxtime;

        playableDirector.time = actTime;
        playableDirector.RebuildGraph();
        playableDirector.Play();
        playableDirector.playableGraph.GetRootPlayable(0).SetSpeed(0);

    }

i had to rebuild the graph because otherwise playableGraph.GetRootPlayable(0) finds no graph - maybe i didnt understand the concept but actually there is a timeline graph in the scene already - nevertheless by setting the speed to 0 and resetting the time i was able to control the time of a timeline manually

3 Likes

It worked for me. Thanks!

1 Like

Hi @seant_unity sorry for the necro, just wanted to thank you for this additional note. I’m using a similar approach where I have the player “scrob” through a Timeline animation. I’ve been looking to solve a problem where Signal Emitters would fire off multiple times when set to fire retroactively. The addition of a playableDirector.playableGraph.IsValid() is false check made the difference, and spares me having to roll my own custom Signal Emitters, phew!

Cheers.

(Edit: turns out I now need to figure out a way of triggering Signal Emitters when moving backwards through the timeline though, as it seems that I was relying on the events continuously firing, to restore certain scene elements to a previous state…)

1 Like

Hello dude is this snippest code for scrubbing timeline in runtime using a slider?

That will work, but you should only rebuild the graph and start playing if playableDirector.playState == PlayState.Paused. Otherwise each time you call this method, you will reconstruct the entire timeline instance, which can be very costly.

1 Like

Hey
Can you clearify this?
Maybe telling a bit more , with some simple codes?

private void setTime() {

        Scrollbar Scrollbar = scroll.GetComponent<Scrollbar>();
        PlayableDirector playableDirector = GetComponent<PlayableDirector>();
        Debug.Log(Scrollbar.value);
        float maxtime = 1;
        actTime = Scrollbar.value * maxtime;
        if (playableDirector.state == PlayState.Paused) 
        {
            // this will call RebuildGraph if needed
            playableDirector.Play();

            // will set the speed of the graph to 0, so it's always playing but never
            // advancing
            playableDirector.playableGraph.GetRootPlayable(0).SetSpeed(0);
        }

        playableDirector.time = actTime;

    }
3 Likes

Thank you @seant_unity

I don’t know if this is better or not, but I hooked up the slider directly to the setTime function and it worked well.

   public PlayableDirector m_playable;

    public void setTime(Vector2 value)
    {
        //Invert slider value
        float t = Mathf.Lerp(1, 0, value.y);
        double maxtime = m_playable.duration;
        double actTime = t * maxtime;
        if (m_playable.state == PlayState.Paused)
        {
            // this will call RebuildGraph if needed
            m_playable.Play();

            // will set the speed of the graph to 0, so it's always playing but never
            // advancing
            m_playable.playableGraph.GetRootPlayable(0).SetSpeed(0);
        }

        if (actTime < 0)
            actTime = 0;
        if (actTime > maxtime)
            actTime = maxtime;
        m_playable.time = actTime;

    }