Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question [Sequences] Is there no way for a sub-sequence to pause the timeline?

Discussion in 'Timeline' started by Invertex, Feb 24, 2023.

  1. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,557
    Using Sequences, I have my Master Sequence, which then has child sequences, and those sequences have further children, as is shown in some example projects.

    I need sub-sequences to be able to change the time of the Timeline, but for example on
    ProcessFrame(Playable playable, FrameData info, object playerData)
    , calling
    playable.SetTime(time)
    doesn't seem to actually change the time of the graph. It's only if I directly reference the Master Timeline and set time on that, will it actually change the time.

    Is it necessary to reference the master timeline to do any time changing? If so, is there a way to actually get the master timeline without having to bind it to my tracks?
     
  2. akent99

    akent99

    Joined:
    Jan 14, 2018
    Posts:
    588
    I think its the master timeline that knows the "real" time. That is where you seek to. From that timeline, it can work out which sub-timeline to apply, but its all driven from the master timeline. So I am not surprised you have to update the master timeline playable. (It would stomp on any child changes I assume.)

    How to find the master timeline from a nested timeline? It depends on which version of the Sequences package you are using. For example, the most recent version of Sequences lost some access to some fields (hopefully coming back in next version of API), so C# Reflection was needed to pull the innards out of some data structures for what I was trying to do. For example: https://github.com/alankent/Ordinar...ry Cartoon Maker/Scripts/SequencesApi.cs#L135 (This project might have some useful snippets of code to browse around sequence hierarchies. In my case I know the name of the nodes in the scene hierarchy, so sometimes I can just drill down through the scene hierarchy to get where I want.)
     
  3. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,557
    Yeah I figured as much, but hoped they had a feedback chain for the time commands on children, seems not though.

    That's a neat bit of info about the MasterSequence property, thanks. Though it doesn't seem too useful in my case as there doesn't seem to be an obvious way to go from MasterSequence to PlayableDirector, which is where the time controls are.

    For now I've resorted to an automatic traversal up the GameObject hierarchy on track creation to find a custom component on the master PlayableDirector and bind it. Not as clean as I'd like but I guess it will have to do.
     
    Last edited: Feb 24, 2023
  4. akent99

    akent99

    Joined:
    Jan 14, 2018
    Posts:
    588
    I now use the game object hierarchy to move around timelines. I started moving around via sequences api, but it’s being thinned out and the game objects have more information like the track bindings. So conceptually I think navigating via game objects is safer in the long term.
     
  5. JunL_Unity

    JunL_Unity

    Unity Technologies

    Joined:
    May 28, 2020
    Posts:
    18
    Hey there
    So I don't fully understand your use case but Timeline does provide a
    TimelineEditor.masterDirector
    property that returns the root PlayableDirector of the timeline currently shown in the Timeline Window. So when you're in a nested timeline, as is often the case when using Sequences, the function will return the root PlayableDirector which should be the MasterTimeline's PlayableDirector. Then from there you can manipulate time, as you've seen.
    Let me know if this helps! Thanks :)
     
    M4R5 and akent99 like this.
  6. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,557
    This would only work within the Editor though. I need this to work as a function of my timelines for actual gameplay. But I guess this will help for setting up when I need it for a track bind! Thanks

    Basically I had to create a Timeline system to support a branching dialogue system with animated scenes, which many RPG/Adventure/Story games involve. Timeline would react to the flow of Dialogue and choices made, playing animations/audio/etc and loading assets where needed, allowing a given interaction event with a character/system to be contained within one Master sequence. This would also keep production simplified as a given interaction can be designed with one continuous flowing timeline and one-time necessary asset loads instead of unloading/loading of assets between distinct Master timeline loads.

    As with many of these games, the flow of dialogue animations/audio should wait for the player to confirm reading the text before continuing to play more, so a child Sequence needs to be able to pause the whole timeline (SetSpeed(0) more accurately). I didn't want to have to create an entirely new Timeline for every line of text, as that would quickly grow to ridiculous proportions and make directing of the scene tricky.

    And because there are multiple choices in dialogue, different child sequences will be enabled based on that choice, and these children being branches will be of varying length to each other. So these child Sequences also need to be able to skip the Timeline ahead to where all the dialogue choices (potentially) finally converge back to common dialogue. (This also has the added benefit of being able to still easily layer things on top that might be shared by all choices)

    Basically, think like how Genshin Impact's cutscene dialogue works, if you've every played that. They too use Unity and Timelines (though before Sequences were a thing).

    Anyways, I have my system working, was just hoping the Timeline system itself would be passing the Master Timeline down the chain to give children in the PlayableGraph reference to the root. Then also the PlayableExtensions functions could actually operate when being used on a child playable, as currently they get called but most won't do anything since the Master is in control, but with no warning about that.
     
    JunL_Unity likes this.
  7. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,557
    Using the trick you mentioned earlier with the reflected field, I did figure out a more secure way to ensure I've found the master PlayableDirector without requiring a custom component to be added first. Maybe you already thought of it, but basically after grabbing the MasterSequence reference from that, traverse the parents, checking for a PlayableDirector component, and if the
    playableDirector.playableAsset == masterSequence.masterTimeline
    then you've found your root PlayableDirector.

    It would probably also be fine to just traverse until GetComponent<PlayableDirector>() returns null, but I wanted to cover all potential edge cases.

    Seems about as clean as it will get for working outside the Timeline editor.
     
    akent99 likes this.
  8. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,321
    Hey, I'm facing a similar issue. Not using sequences though.

    I have a sub timeline being controlled by a ControlTrack. The sub timeline contains custom playables that pause time while dialogue plays out. However, on a sub timeline, the playables do nothing. The root graph is unaffected.

    playable.GetGraph().GetRootPlayable(0).SetTime(someTime);

    does nothing when called from a playable behaviour on a sub timeline