Search Unity

  1. Calling all beginners! Join the FPS Beginners Mods Challenge until December 13.
    Dismiss Notice
  2. It's Cyber Week at the Asset Store!
    Dismiss Notice

Is there a way to guarantee the timeline will pause without crossing a certain threshold?

Discussion in 'Timeline' started by jmdodge, Sep 13, 2019.

  1. jmdodge

    jmdodge

    Joined:
    Jan 3, 2019
    Posts:
    3
    Not sure of a better way to word the title, but basically what I'm doing is this:

    I have a timeline that's meant to be an interactable series of events. For illustration purposes, say:
    1. A box appears
    2. A clip on the timeline executes an arbitrary event that says: pause the timeline until a button is pushed.
    During this time, the box should stay visible.
    3. Pushing the button resumes the timeline, which deactivates the box so that it disappears.

    The problem I'm happening is that by the time the event telling the timeline to pause has executed, my box has already disappeared because the play head has moved past the point where it was supposed to stop.


    I could create a longer "buffer zone" to catch the pause command, but that also means that when a button is pushed, there is a little delay as it plays through the buffer zone to the next part. This is a pretty brittle solution anyway and if the frame rate goes low enough may not even work.

    I tried changing the "Update Method" of the playable director to "Unscaled Game Time", and this seems to reliably get the timeline to pause on the same frame as the pause event, but I don't understand it well enough to feel confident that this is going to work reliably if the frame rate of the game gets wonky.

    I should say also, I'm using an asset from the asset store to execute my events on the timeline: https://assetstore.unity.com/packages/3d/characters/timeline-events-115300

    It uses clips that are configured to execute a unity event. Not sure if there would be any difference with using markers or the built in "signal" system.


    Any advice is appreciated, thanks!
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,068
    In general no, at least not in a single timeline. The reason is exactly what you observe - there is no guarantee of landing at an exact time. Timeline is sample at intervals determined by the current frame rate, which can fluctuate.

    An alternative is to manually advance using smaller timesteps (similar to fixed update loop), but this has a few drawbacks. In particular, Timelines signals won’t fire from manual updates, nor will audio play correctly.

    The other alternatives are to use multiple timelines, or some of the time jump mechanisms found here.
     
  3. jmdodge

    jmdodge

    Joined:
    Jan 3, 2019
    Posts:
    3
    Thank you for your reply!

    Regarding the "time jump" mechanisms you referenced in the blog post, that seems like the ideal solution for me - but I'm a little confused.

    In the first portion of the post there is "Idea 1 – Stopping the Timeline", wherein the author pauses the timeline while dialogue is visible and waits for the user to press the spacebar in order to advance. This is exactly what I'm trying to do!

    What is it that prevents the timeline stopping at exactly the right spot in this instance? In order to work as intended, the dialogue box needs to remain visible on the screen, but if the playhead were to go a single frame beyond the stop point, presumably the dialogue box would be deactivated or no longer visible.

    Supposing the above is accomplished by rewinding the playhead back to the exact point on the timeline where it was supposed to stop, what prevents events from occurring that may be on the subsequent frames (like sounds playing or some game event being invoked)? In other words, suppose I want to stop on frame 5, and on frame 6 I trigger a spawn event, but Unity doesn't sample the timeline until frame 7. In that case it could stop and rewind back to frame 5, but it can't "undo" the spawn event on frame 6, right? Or maybe there's a way to stop the cascade of events on passed frames from running once you say "stop"?

    Thanks in advance for your time!
     
  4. ewanuno

    ewanuno

    Joined:
    May 11, 2017
    Posts:
    39
    from the unity blog post about timeline signals (https://blogs.unity3d.com/2019/05/21/how-to-use-timeline-signals/)

    "Are signals guaranteed to be emitted? Yes. Signals will not be skipped; they will be emitted on the next frame regardless of the game’s FPS."


    i'm doing something very similar, (pause signal stops the main timeline) pointer click restarts it via an event trigger on a UI panel.

    knowing that there might be a frame or so of delay before the timeline stops,(and potentially when it starts again)
    i leave at least 5 frames between the marker and the next clip on the timeline just to be safe, it seems to be working fine so far, but i haven't really tested on drastically underpowered devices yet.
     
  5. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,068
    There is no way to 'undo' signals/events. Adding in padding is one way to do it, but as ewanuno mentioned it can be fragile because of frame rate.

    Instead of spawning, you can use an activation clip on a pre-spawned object in the scene. In that case, rewinding would work, unless the spawned object causes another object to change in some way.

    If you need to rewind, then you need to make sure the timeline is deterministic. Signals break determinism - they cause a state change that timeline does not know how to restore. The time machine example is deterministic.
     
  6. jmdodge

    jmdodge

    Joined:
    Jan 3, 2019
    Posts:
    3
    So my options are:
    1. Add some padding at stop points to ensure the timeline doesn't end up passing into an undesirable state. Live with the fact that a crazy bad frame rate could still break this. Use markers to jump ahead to the next section when triggered.
    2. Handle overrun stop points by rewinding, but this won't work with signals or other arbitrary events because there's no way to prevent them from executing if the play head overruns a stop point where they occur (I'm using these types of signals).
    3. Multiple timelines. I think this would cause me some problems with managing the state of the objects that are in the timeline, e.g.holding vs resetting position of the bound objects and how the interaction would be with several timelines working in sequence... I have to think about that some more I guess. Also it somewhat spoils the convenience and ease-of-use that this approach offers in the first place - I like being able to work with a long/complicated sequence in one place.

    Honestly, none of these really feel like great or elegant solutions, but I suppose something is workable.

    Is there any other recommended approach for what I'm trying to do? Working with long, complex animation sequences where there is some dynamic user interaction in between sections of that sequence?
     
  7. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,068
    So, the trick here would be to prevent the time from moving past a certain point. This is exactly what the Hold option on the playable director does.

    Seeing that none of those you've listed are really good options, I made a little test track/clip that modifies the duration of the timeline and the wrap mode on the fly. The clip area is the time to accept input, if no input is given then it waits at the end of the clip.

    I hope that helps.
     

    Attached Files: