LoginSignup
2
1

More than 3 years have passed since last update.

UnityのTimelineでクリップが一つだけのトラックを作る

Last updated at Posted at 2019-12-04

こんにちは、ZeniZeniです。
最近Unityのタイムラインをよくいじっています。

やりたいこと

Unityのタイムラインをいじっていると、トラック上にクリップが一つだけしか存在してはいけないような制限を設けたいときがあります。(私はありました。)

さぁ作ろうと思って色々調べてみると、カスタムPlayable Trackでタイムラインのトラックを自作しないといけないことがわかりました。
こちらの動画が参考になります。
https://youtu.be/6SPpjSKy9LI

上の動画を参考にしながら、トラックにクリップが二つ以上置けない制限を設けた、シーン遷移を行うカスタムトラックを作成しました。
プロジェクトはこちらにあります。
https://github.com/Zeni-Y/TimelineCustomTrackTest

実装方法

まず、作製したMixerとTrackのコードはこちらです。(プラスClipとBehaviourのコードもありますが、長くなるので割愛します)

SceneManagementMixer
using System.Collections.Generic;
using UnityEngine.Playables;
using UnityEngine.Timeline;
using System.Linq;
using UnityEngine.SceneManagement;

namespace ZeniZeni.CustomTrack
{
    public class SceneManagementMixer : PlayableBehaviour
    {

        internal PlayableDirector m_playableDirector;

        internal string m_scene;
        internal LoadSceneMode m_mode;

        internal IEnumerable<TimelineClip> m_clips;
        private bool oneShot = true;

        // NOTE: This function is called at runtime and edit time.  Keep that in mind when setting the values of properties.
        public override void ProcessFrame(Playable playable, FrameData info, object playerData)
        {
            if (m_clips.Count() >= 2) return;

            int inputCount = playable.GetInputCount<Playable>();
            if (inputCount == 0) return;

            var time = m_playableDirector.time;
            var enumulator = m_clips.GetEnumerator();
            enumulator.MoveNext();

            for (int i = 0; i < inputCount; i++, enumulator.MoveNext())
            {
                var clip = enumulator.Current;

                var asset = clip.asset as SceneManagementClip;

                m_scene = asset.m_scene;
                m_mode = asset.m_mode;
                if (clip.start <= time && time <= clip.end  && oneShot)
                {
                    SceneManager.LoadSceneAsync(m_scene, m_mode);
                    oneShot = false;
                }
                else if (time < clip.start || time > clip.end)
                {
                    if (!oneShot) oneShot = true;
                }
            }

        }
    }
}
SceneManagementTrack.cs
using System.Linq;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

namespace ZeniZeni.CustomTrack
{
    [TrackColor(0.3523021f, 1f, 0f)]
    [TrackClipType(typeof(SceneManagementClip))]
    public class SceneManagementTrack : TrackAsset
    {

        public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
        {

            var mixer = ScriptPlayable<SceneManagementMixerBehaviour>.Create(graph, inputCount);
            var director = go.GetComponent<PlayableDirector>();
            if (director != null)
            {
                SceneManagementMixerBehaviour bh = mixer.GetBehaviour();
                //Track上のクリップを取得
                bh.m_clips = GetClips();

                //Clipが二つ以上あれば一つだけになるようにClipを新しい順に消す
                if (bh.m_clips.Count() >= 2)
                {
                    for (int i = 0; i < bh.m_clips.Count()-1; i++)
                    {
                        timelineAsset.DeleteClip(bh.m_clips.Last());
                    }
                    Debug.Log("You can put only one SceneManagementClip in this Track.");
                }
                bh.m_playableDirector = director;
            }

            return mixer;
        }
    }
}

クリップを二つ以上置けないようにする機能の実装方法ですが、クリップを作成したときに、そのトラック上にクリップが二つ以上存在すれば、一つだけになるようにClipを新しい順に消すような形で実装しています。

クリップを二つ以上置こうとすると以下のGIFのようになります。
ダウンロード.gif

ただ問題がありまして、インスペクターを表示した状態でこの動作を行うと、下の画像のようなエラーが発生します。
bandicam 2019-12-01 23-32-49-404.jpg

一応Clearで簡単に消せますが、気になっちゃいますよね。

理想としては、クリップが一つ存在すれば追加でクリップを作成できないような形にしたかったんですが、実装方法がわからず断念しました。
方法がわかり次第、追記していきます。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1