I am trying to implement a pause system for timelines so everything “holds” instead of stops evaluating. I am setting the time manually through playableDirector.time. This all works fine, except audio tracks no longer play at all.
If I attach this to my timeline GameObject:
public class TimelineController : MonoBehaviour {
public PlayableDirector timeline;
public bool playing;
// Use this for initialization
void Start () {
timeline = GetComponent<PlayableDirector>();
playing = true;
}
// Update is called once per frame
void Update () {
timeline.time = timeline.time + Time.deltaTime;
timeline.Evaluate();
}
}
and hit play. I get the timeline playing forward, but no sound. If I change the PlayableDirector back to Update Method: Game Time , everything works.
Yes, prior to 2018.2 audio playables ignore Evaluate() calls completely.
Depending on the desired result, there are a couple ways to make a better ‘Pause’ in playable director. Some suggestions
if you are using Audio, and don’t need to scale time use DSP time to drive the timeline. Audio always runs off the DSP clock, so driving timeline with it will better keep them in sync.
you can use playableDirector.playableGraph.GetRootPlayable(0).SetSpeed(0); to ‘Hold’ a timeline, but that may not have the desired behaviour for audio.
Alternatively, let the timeline playback normally and use the Pause() and Resume(), and only Evaluate() when the timeline is paused. This should hold all other tracks and ignore audio. But beware - Evaluate() is more expensive than normal playback, since it runs everything single threaded and waits for the results.
I hope that helps. I better ‘Pause’ is on list of areas to improve, and something I hope we can better address soon!
The Pause Resume and Evaluate solution works perfectly for what I’m trying to do. I gathered that it has something to do with Audio using a different clock but that’s as far as I could go.
I look forward to proper Pause/Hold, but this will do for now.
I’m using 2018.2.13f1 and also experiencing no audio playing when using manual update mode for timelines.
Here’s a snippet of the code that does the timeline updating (also has logic for looping and holding, since it appears the wrap mode is ALSO ignored in manual time update mode - another undocumented API issue IMO):
Code in Start method to set the timeline to manual update:
And then the code in my Update method that updates the playable:
director.time += (deltaTime * timeScale);
switch (director.extrapolationMode)
{
case DirectorWrapMode.Hold:
if (director.time > director.duration)
director.time = director.duration;
break;
case DirectorWrapMode.Loop:
director.time = (director.time % director.duration);
break;
default:
Debug.LogError(
string.Format("Director '{0}' {1} must either be set to '{2}' or '{3}' (currently '{4}'), otherwise it'll never end",
director.name, nameof(PlayableDirector.extrapolationMode), nameof(DirectorWrapMode.Hold), nameof(DirectorWrapMode.Loop), director.extrapolationMode));
break;
}
director.Evaluate();
Is this fixed in 2018.3 so that audio continues playing when you manually update timelines? at the very least, this limitation should be added to the documentation so that folks using manual mode know what they are getting themselves into…
@seant_unity thanks for the response. Is there any plans to support reduced-speed audio playback for manual mode?
if not, how would you suggest playing audio at a reduced speed when you slow down a timeline? Our use case is a freeze effect in an action RPG that slows characters down to a crawl and then freezes them
One way to do it is change the speed the graph plays. E.g.
var director = GetComponent<PlayableDirector>();
if (director != null && director.playableGraph.IsValid())
director.playableGraph.GetRootPlayable(0).SetSpeed(timeScale);