【Unity】Timelineでミュート状態をランタイムで動的に切り替える方法

UnityのTimelineでミュート状態をランタイムで動的に切り替える方法についてまとめました。

Unity2022.3.28f1

やりたいこと

TimelineではTimelineウィンドウのトラックのミュートボタンを押すことでそのトラックをミュートし、再生対象から除外することができます。

ミュート
本記事ではこれをランタイムでスクリプトから動的に切り替える方法についてまとめます。

実装

それでは早速スクリプトを実装します。

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

public sealed class Example : MonoBehaviour
{
    public PlayableDirector director;
    public string targetGameObjectName;

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
            ToggleMute(targetGameObjectName);
    }

    /// <summary>
    ///     指定したトラックのミュート状態をトグルする
    /// </summary>
    /// <param name="trackName"></param>
    private void ToggleMute(string trackName)
    {
        var timelineAsset = (TimelineAsset)director.playableAsset;

        foreach (var track in timelineAsset.GetRootTracks())
        {
            // TrackにバインドされているGameObjectを取得する
            var boundGameObject = (GameObject)director.GetGenericBinding(track);

            if (boundGameObject.name != trackName)
                continue;

            track.muted = !track.muted;
        }

        // ミュート状態を変更したらグラフをリビルドする必要がある
        var time = director.time;
        director.RebuildGraph();
        director.time = time;
    }
}

説明はコメントに書いた通りです。

TrackAsset.mute を変えるだけではミュート状態は反映されず、PlayableGraph をリビルドする必要がある点に注意してください。
このことから、基本的にはランタイムではあまり頻繁にミュート状態を切り替えるべきではないものと思われます。

スペースキーを押したら targetGameObjectName に一致する名前のGameObjectがバインドされているトラックのミュート状態がトグルされます。

実行結果

これを適当な GameObject にアタッチして、Inspector から Director と Target Game Object Name を設定し、再生後にスペースボタンを押すとミュート状態が切り替わることを確認できます。

実行結果