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

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:

using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

[RequireComponent(typeof(PlayableDirector))]
public class TimelineTest : MonoBehaviour
{
    public TimelineAsset[] TimelineAssets;
    public float Step = 1.0f;

    private PlayableDirector director;
    private float elapsedTime;
    private int index;

    private void Start()
    {
        this.director = this.GetComponent<PlayableDirector>();
        this.director.Play(this.TimelineAssets[0]);
    }

    private void Update()
    {
        this.elapsedTime += Time.deltaTime;

        if (this.elapsedTime >= this.Step)
        {
            this.index++;

            if (this.index >= this.TimelineAssets.Length)
            {
                this.index = 0;
            }

            this.director.Play(this.TimelineAssets[this.index]);
            this.elapsedTime = 0;
            Debug.Log($"Timeline is changed : {this.index}");
        }
    }
}

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.

Also I found that PlayableDirector.Stop() +PlayableDirector.Play() without changing PlayableAsset generates GC too.

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.

1 Like

Also, Stop() destroys the graph, so Stop() then Play() will cause GC to occur. Pause() keeps the graph alive, but doesn’t execute it.

@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?