【Unity】ネストされたタイムライン(子タイムライン)をスクリプトから作成する方法

Unityネストされたタイムライン(子タイムライン)をスクリプトから作成する方法についてまとめました。

ネストされたタイムライン?

UnityのTimelineでは、PlayableDirectorをTimelineウィンドウにドラッグ&ドロップすることで、別のタイムラインをクリップとして制御できます。

ネストされたタイムライン

上図ではUnityエディタ上でネストされたタイムラインを作成していますが、スクリプトから作ることもできます。
本記事ではこれを行う方法をまとめます。

スクリプトから作成する方法

ネストされたタイムラインをスクリプトから作成するには以下のようにします。

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

public sealed class Example : MonoBehaviour
{
    // ネスト対象のPlayableDirector
    [SerializeField] private PlayableDirector director;

    private void Start()
    {
        // 新しいTimelineアセットを作る(これの中にNested Timelineを作成する)
        var timelineAsset = ScriptableObject.CreateInstance<TimelineAsset>();

        // PlayableDirectorを作って↑を設定
        var newPlayableDirector = gameObject.AddComponent<PlayableDirector>();
        newPlayableDirector.playableAsset = timelineAsset;

        // トラックとクリップを作成
        var controlTrack = timelineAsset.CreateTrack<ControlTrack>(null, "Nested Timeline");
        var clip = controlTrack.CreateClip<ControlPlayableAsset>();
        clip.displayName = "Nested Timeline";
        clip.start = 3.0f; // 適当に開始時間をずらしておく
        clip.duration = director.playableAsset.duration;
        var controlPlayableAsset = (ControlPlayableAsset)clip.asset;

        // ControlPlayableAssetのsourceGameObjectにネスト対象のPlayableDirectorを設定
        // ExposedReferenceを使っているので名前で紐付ける必要がある
        // 名前は任意だが、もし非ランタイムでのみ生成する場合にはUnityEditor.GUID.Generate().ToString()
        // を使ったほうがSource Game ObjectのInspector表示が良い感じになるのでおすすめ
        var sourceGameObjectExposedName = Guid.NewGuid().ToString();
        controlPlayableAsset.sourceGameObject.exposedName = sourceGameObjectExposedName;
        newPlayableDirector.SetReferenceValue(sourceGameObjectExposedName, director.gameObject);
    }
}

説明はコメントに書いた通りです。
Playable Director との紐付けは ExposedReference で行う必要がある点がポイントです。

動作確認

このスクリプトを適当なGameObjectにアタッチし、directorプロパティにネスト対象のPlayableDirectorをアサインし、再生すると下図のようにタイムラインが生成されます。

動作確認

ネストされたタイムラインが生成されていることを確認できました。

参考

docs.unity3d.com