Unity 2019.1から、Timelineで任意のメソッドを呼び出すSignalsという仕組みが導入されました。 開発中に、これスクリプトで追加したくなったので、その方法について記載します。
Signalsとは?
SignalsはTimelineから指定したフレームにTimeline外の特定の処理を行うための機能です。Animationについて知見のある方は、TimelineにおけるAnimationEventという理解で概ね問題ないと思います。
下図の赤枠内にマークが設定されてますが、これがSignalです。タイムライン中にSignalを仕込むことができます。そのSignalから任意のメソッドを呼び出したり、Receiverを用意することで、Signalの発火タイミングを受け取ることができます。
Timelineを使っているとAnimationEventに相当する機能を実装したくなることがありますが、これを実現するために独自のTrack実装することになります。ただ任意のメソッドを呼び出すために独自Trackを実装するのは地味に大変なので、個人的にはこのような用途では有用だと感じています。
Signalsをスクリプトから追加する
今回は、下記のSignalクラスをスクリプトからTimelineに追加することをゴールとします。
using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
[Serializable]
public class MyNotification : Marker, INotification
{
    public PropertyName id { get; }
}作成するエディタ拡張は下記動画の通りです。

MarkerTrack
Signalを追加するには、まずタイムラインにMarkerTrackを作成する必要があります。MarkerTrackはエディター中のTimelineビューの下図赤枠のことを指します。
Marker TrackはTimeline Asset作成直後には作成されていません。この状態でスクリプトからSignalを追加しようとすると、null reference exceptionを吐くため、事前に作成しておく必要があります。
Trackは、上図の上中央のピンのアイコンをクリックしてはじめてMarker Trackを表示した際に作成されます。また、スクリプトでも下記のように追加できます。
// assetはTimelineAsset
var timelineAsset = asset as TimelineAsset;
Assert.IsNotNull(timelineAsset);
// Marker Trackを追加する
timelineAsset.CreateMarkerTrack();作成済みの状態でCreateMarkerTrack呼び出すと2重にTrackを作成しそうですが、Marker Trackは、Timeilne Asset中で1つ保持するような仕組みになっているため問題ありません。
具体的には、CreateMarkerTrackは下記のような実装になっています。
public void CreateMarkerTrack()
{
    // メンバー変数で1つMarkerTrackを保持している
    if (m_MarkerTrack == null)
    {
        m_MarkerTrack = CreateInstance<MarkerTrack>();
        TimelineCreateUtilities.SaveAssetIntoObject(m_MarkerTrack, this);
        m_MarkerTrack.parent = this;
        // This name will show up in the bindings list if it contains signals
        m_MarkerTrack.name = "Markers";
        Invalidate();
    }
}Signalを追加する
あとは、Signalをスクリプトで追加します。具体的には、上記で作成したMarker TrackのCreateMarker<T>を呼び出します。
Timeline Asset内のMarker TrackはmarkerTrackプロパティでアクセスできます。(参考: Class TimelineAsset | Package Manager UI website)
// 戻り値は追加したマーカー
timelineAsset.markerTrack.CreateMarker<MyNotification>(time);引数にはSignalをタイムライン中のどこに追加するかを秒数を指定します。
前述した通り、Marker Trackを作成してない場合はmarkerTrackがnullになっているので注意が必要です。
まとめ
Signalをスクリプトから追加する方法を紹介しました。最後に、今回実装したコードの全容を示します。
using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.Playables;
using UnityEngine.Timeline;
namespace Editor
{
    public class MyNotificationEditor : EditorWindow
    {
        [MenuItem("Window/MyNotification Editor")]
        public static void Open()
        {
            var window =
                (MyNotificationEditor) EditorWindow.GetWindow(
                    typeof(MyNotificationEditor));
            window.Show();
        }
        private void OnGUI()
        {
            _asset =
                (PlayableAsset) EditorGUILayout.ObjectField("target",
                    _asset,
                    typeof(PlayableAsset), true);
            if (_asset != null)
            {
                _time = EditorGUILayout.DoubleField("time", _time);
                if (GUILayout.Button("Add a marker"))
                {
                    AddMyNotificationMarker(_asset, _time);
                }
            }
        }
        private void AddMyNotificationMarker(PlayableAsset asset, double time)
        {
            var timelineAsset = asset as TimelineAsset;
            Assert.IsNotNull(timelineAsset);
            if (timelineAsset.markerTrack == null)
                timelineAsset.CreateMarkerTrack();
            // 戻り値は追加したマーカー
            timelineAsset.markerTrack.CreateMarker<MyNotification>(time);
        }
        private PlayableAsset _asset = null;
        private double _time = 0.0;
    }
}参考
- Class MarkerTrack | Package Manager UI website
- MarkerTrackの公式ドキュメント
 
 - 【Unity】Timelineからメソッドを呼ぶ新機能 「Marker」と「Signal、Signal Receiver」 - テラシュールブログ
- テラシュールブログさんによるSignalの解説ブログ
 
 - [Unity] 分かった気になる! Timeline Signals / Timeline Signals Tutorial
- 青木ととさんによるSignalの解説スライド