Search Unity

How to change/select timeline for playing in runtime efficiently?

Discussion in 'Timeline' started by Kichang-Kim, Aug 7, 2019.

  1. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    1,012
    Hi. I'm trying to make component which has multiple timeline and play one of that by scripting in runtime.

    But it seems that PlayableDirector.Play(PlayableAsset) makes tons of GC. Here is my test code:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Playables;
    3. using UnityEngine.Timeline;
    4.  
    5. [RequireComponent(typeof(PlayableDirector))]
    6. public class TimelineTest : MonoBehaviour
    7. {
    8.     public TimelineAsset[] TimelineAssets;
    9.     public float Step = 1.0f;
    10.  
    11.     private PlayableDirector director;
    12.     private float elapsedTime;
    13.     private int index;
    14.  
    15.     private void Start()
    16.     {
    17.         this.director = this.GetComponent<PlayableDirector>();
    18.         this.director.Play(this.TimelineAssets[0]);
    19.     }
    20.  
    21.     private void Update()
    22.     {
    23.         this.elapsedTime += Time.deltaTime;
    24.  
    25.         if (this.elapsedTime >= this.Step)
    26.         {
    27.             this.index++;
    28.  
    29.             if (this.index >= this.TimelineAssets.Length)
    30.             {
    31.                 this.index = 0;
    32.             }
    33.  
    34.             this.director.Play(this.TimelineAssets[this.index]);
    35.             this.elapsedTime = 0;
    36.             Debug.Log($"Timeline is changed : {this.index}");
    37.         }
    38.     }
    39. }
    40.  
    Methods which generate GC are here:
    Is there any way for selecting/playing Timeline effectively, especially without GC? My goal is that make responseive object that playing timeline for its state.

    Thanks.
     
  2. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    1,012
    Also I found that PlayableDirector.Stop() +PlayableDirector.Play() without changing PlayableAsset generates GC too.
     
  3. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    You can use playableDirector.RebuildGraph() to prep the timeline to play, without actually starting it. That is where most of the allocations occur. Call that somewhere that the GC hit is more acceptable, then call Play() when you need it.
     
    SolarFalcon likes this.
  4. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    Also, Stop() destroys the graph, so Stop() then Play() will cause GC to occur. Pause() keeps the graph alive, but doesn't execute it.
     
  5. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    1,012
    @seant_unity Thanks for reply. In my understanding, the best way to reuse multiple timeline without GC is that using Pause() + set time to 0 instead of Stop(), and holds multiple PlayableDirector because PlayableDirector can play only one timeline, right?