Search Unity

Audio track does not play audio when update mode set to manual

Discussion in 'Timeline' started by kenney001, Apr 12, 2018.

  1. kenney001

    kenney001

    Joined:
    Mar 3, 2015
    Posts:
    1
    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:

    Code (CSharp):
    1.  
    2. public class TimelineController : MonoBehaviour {
    3.  
    4.     public PlayableDirector timeline;
    5.  
    6.     public bool playing;
    7.  
    8.     // Use this for initialization
    9.     void Start () {
    10.         timeline = GetComponent<PlayableDirector>();
    11.         playing = true;
    12.     }
    13.    
    14.     // Update is called once per frame
    15.     void Update () {
    16.         timeline.time = timeline.time + Time.deltaTime;
    17.         timeline.Evaluate();
    18.     }
    19.  
    20.  
    21. }
    22.  
    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.

    Is there something I'm missing here?
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    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!
     
    ho-sik likes this.
  3. kenney003

    kenney003

    Joined:
    Oct 19, 2017
    Posts:
    3
    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.

    Thanks!
     
  4. panta

    panta

    Joined:
    Aug 10, 2012
    Posts:
    71
    Hi,

    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:
    Code (CSharp):
    1. director.timeUpdateMode = DirectorUpdateMode.Manual;
    And then the code in my Update method that updates the playable:
    Code (CSharp):
    1.                     director.time += (deltaTime * timeScale);
    2.  
    3.                     switch (director.extrapolationMode)
    4.                     {
    5.                         case DirectorWrapMode.Hold:
    6.                             if (director.time > director.duration)
    7.                                 director.time = director.duration;
    8.                             break;
    9.                         case DirectorWrapMode.Loop:
    10.                             director.time = (director.time % director.duration);
    11.                             break;
    12.                         default:
    13.                             Debug.LogError(
    14.                                 string.Format("Director '{0}' {1} must either be set to '{2}' or '{3}' (currently '{4}'), otherwise it'll never end",
    15.                                 director.name, nameof(PlayableDirector.extrapolationMode), nameof(DirectorWrapMode.Hold), nameof(DirectorWrapMode.Loop), director.extrapolationMode));
    16.                             break;
    17.                     }
    18.  
    19.                     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...
     
  5. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Yes, its a known limitation that audio doesn't play with manual mode. You are right, we should add that to the docs.
     
  6. panta

    panta

    Joined:
    Aug 10, 2012
    Posts:
    71
    @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
     
  7. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    One way to do it is change the speed the graph plays. E.g.

    Code (CSharp):
    1.        var director = GetComponent<PlayableDirector>();
    2.         if (director != null && director.playableGraph.IsValid())
    3.             director.playableGraph.GetRootPlayable(0).SetSpeed(timeScale);