本記事は、Unity AdnventCalender 2024 の16日目の記事となります。
※枠が空いていたので代わりに投稿させていただく形となりました。12/25なのでギリギリセーフ。。。
概要
タイトルの通りですが、今回はUnityの機能の一つであるTimelineのMarkerの機能拡張の記事となります。そのため、Timeline, Markerに関しての基礎知識は既にある前提とします。
TimelineやMarkerに関する基礎知識・使い方に関しては、既に様々な方が良記事をネットで公開しているため、今回は省略します。
MarkerはどのTrackでも置ける
TimelineでMarkerを使用する際には、以下のようなコードを書くと思います(INotification等は今回は省略)
using UnityEngine.Timeline;
public class NormalMarker : Marker
{
}
上記のようなカスタムMarkerクラスを定義すると、TimelineWindowのサブメニューからトラック上にマーカーを設置できるようになります。
しかしこの方法だと、どのトラック上にもマーカーを設置することが出来てしまうため、場合によってはマーカーが散らばって意図しない挙動を起こす危険性もあります。
カスタムMarkerを指定トラックのみ配置したい
本来ならば、指定したトラック上でのみサブメニューを開いた時のみ、「Add ○○ Marker」という項目を出現させるように出来れば良かったのですが、自分では良い方法を見つけられなかったので、今回は割とごり押し気味な方法で実装します。
以下が指定トラックのみ配置可能なカスタムMarkerクラスとなります
※今回はControlTrackを指定していますが、自分で作成したカスタムトラックでも問題ないです
using UnityEngine;
using UnityEngine.Timeline;
public class HogeMarker : Marker
{
public override void OnInitialize(TrackAsset aPent)
{
Debug.Log("Call OnInitialize");
#if UNITY_EDITOR
// ControlTrackのみ配置できるようにする
if (aPent is ControlTrack == false)
{
Debug.LogWarning($"このマーカーは{nameof(ControlTrack)}上のみ配置可能です");
DestroyImmediate(this, true);
}
#endif
}
}
継承元のMarkerクラスには「OnInitialize(TrackAsset aPent)」という仮想関数が定義されており、ここでマーカーの初期化処理を上書きすることができます。この処理はマーカーの生成時にも呼ばれ、引数のTrackAssetにマーカーが配置されたTrackAssetの参照が入るので、ここで配置したいトラックの型かどうかを判定して、違う場合は即座に自分自身(生成したマーカー)を削除します。
上記で作成してHogeMarkerの挙動は以下の通りになります
余談:#if UNITY_EDITORで囲んでいる理由
※#if UNITY_EDITORで囲んでいる理由としては、このOnInitializeはTimelineのデシリアライズにも呼ばれるため、そのままにしておくとアプリ上でTimelineを再生する際に余計な処理不可となってしまうのを避けるためです。
おわりに
かなり突発的に記事を書こうと思い立ったので、内容としては小ネタに近いですが何かの役に立てば幸いです。
また、他の方法やもっと良い手法等あれば、コメントで教えてもらえると有難いです。
検証環境
Windows 11
Unity 2022.3.22f1
Timeline 1.7.6
参考サイト
Class Marker
https://docs.unity3d.com/Packages/com.unity.timeline@1.8/api/UnityEngine.Timeline.Marker.html
Interface IMarker
https://docs.unity3d.com/Packages/com.unity.timeline@1.8/api/UnityEngine.Timeline.IMarker.html