TimelineのMarkerの見た目を変更する

に公開

はじめに

何故かAIに聞いても検索してもイマイチ完全な情報が少なかったので、メモとして書いておきます。

Markerの種類が色々増えてくると、ひと目で区別がつかないため視認性が悪くなってきていました。
そこで、Markerの上にアイコンを重ねて表示するようにして、視認性を向上させることにしました。

環境

Unity 6000.0.46

実装後の見た目

こんな感じで、Markerの上からアイコンを重ねて表示している感じです。
アイコン画像は絵文字です。

timeline_marker_icon

実装方法

Editorにて以下のような親クラスを作成します。

MarkerEditorを継承して、DrawOverlayメソッドをオーバーライドします。

ついでに、GetMarkerOptionsメソッドもオーバーライドして、ツールチップを設定します。これはマウスを合わせたときに表示されます。

using UnityEditor;
using UnityEditor.Timeline;
using UnityEngine;
using UnityEngine.Timeline;

public class IconMarkerEditor : MarkerEditor
{
    public const string PathToIconTextureFolder = "テクスチャフォルダのパス(各自書き換えて下さい)/";
    public const string PngExtension = ".png";
    public const string BackgroundTextureName = "背景のテクスチャ名(各自書き換えて下さい)";

    // 表示するアイコンのテクスチャ画像
    readonly Texture2D _markerTexture;

    // 背景のテクスチャ画像
    readonly Texture2D _backgroundTexture;    

    /// <summary>
    /// アイコンのテクスチャ名
    /// </summary>
    protected virtual string NameOfIconTexture => "";

    public IconMarkerEditor()
    {
        _markerTexture = EditorGUIUtility.Load($"{PathToIconTextureFolder}{NameOfIconTexture}{PngExtension}") as Texture2D;

        if (_markerTexture == null)
        {
            Debug.LogError("Marker texture not found. Please ensure the path is correct.");
        }

        _backgroundTexture = EditorGUIUtility.Load($"{PathToIconTextureFolder}{BackgroundTextureName}{PngExtension}") as Texture2D;

        if (_backgroundTexture == null)
        {
            Debug.LogError("Background texture not found. Please ensure the path is correct.");
        }
    }

    public override MarkerDrawOptions GetMarkerOptions(IMarker marker)
    {
        return new MarkerDrawOptions { tooltip = marker.ToString() };
    }

    public override void DrawOverlay(IMarker marker, MarkerUIStates uiState, MarkerOverlayRegion region)
    {
        if (uiState != MarkerUIStates.Selected) // 選択されていない場合はアイコンを描画しない
        {
            var markerRegionCenter2 = region.markerRegion.xMin + (region.markerRegion.width - 26f) / 2.0f;
            var bgRect = new Rect(
                markerRegionCenter2,
                region.markerRegion.y - 10f,
                26f,
                26f
            );
            
            GUI.DrawTexture(bgRect, _backgroundTexture); // 背景画像を描画
            GUI.DrawTexture(bgRect, _markerTexture); // その上にアイコン画像を描画
        }

        base.DrawOverlay(marker, uiState, region);
    }
}

あとは各マーカーにてファイル名を指定して継承するだけです。
このとき、Markerは専用のアトリビュート[CustomTimelineEditor]を付けておく必要があります。

実装例
using UnityEditor.Timeline;

[CustomTimelineEditor(typeof(TalkLogPlayMarker))]
public sealed class TalkLogPlayMarker : IconMarkerEditor
{
    protected override string NameOfIconTexture => "ledger";
}

[CustomTimelineEditor(typeof(SfxPlayMarker))]
public sealed class SfxPlayMarkerEditor : IconMarkerEditor
{
    protected override string NameOfIconTexture => "musical_note";
}

[CustomTimelineEditor(typeof(BgmStopMarker))]
public sealed class BgmStopMarkerEditor : IconMarkerEditor
{
    protected override string NameOfIconTexture => "muted_speaker";
}

指定した位置に名前(NameOfIconTexture)通りのアイコン画像を配置しておくと、Timeline上でマーカーの上にアイコンが表示されるようになります。

参考

Discussion