ループ再生するクリップの作り方

２つやり方がある
1. ```OnBehaviourPause```でクリップの再生時間を減算する
1. ```OnBehaviourPause```でクリップの開始時間を代入する

まず、再生時間を減算するやり方
```csharp
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

public class LoopBehaviour : PlayableBehaviour
{
    public bool loop = true;

    public override void OnBehaviourPause(Playable playable, FrameData info)
    {
        if (!loop) return;
        
        if(playable.GetGraph().GetResolver() is PlayableDirector director)
            director.time -= playable.GetDuration();
    }
}

```
```csharp
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

public class LoopClip : PlayableAsset, ITimelineClipAsset
{
    public bool loop = true;

    ClipCaps ITimelineClipAsset.clipCaps { get; }

    public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
    {
        var playable = ScriptPlayable<LoopBehaviour>.Create(graph);
        var clone = playable.GetBehaviour();

        clone.loop = loop;

        return playable;
    }
}
```
```csharp
using UnityEngine.Timeline;

[TrackClipType(typeof(LoopClip))]
public class LoopTrack : TrackAsset {}
```

つぎに開始時間を代入するやり方
PlayableBehaviourのclipへTrackAssetで取得したclipをPlayableAssetを経由して代入している

```csharp
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

public class LoopBehaviour : PlayableBehaviour
{
    public bool loop = true;

    public GameObject trackBinding;
    public TimelineClip clip;

    public override void OnBehaviourPause(Playable playable, FrameData info)
    {
        if (!loop) return;
        
        if(playable.GetGraph().GetResolver() is PlayableDirector director)
            director.time = clip.start;
    }
}
```
```csharp
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

public class LoopClip : PlayableAsset, ITimelineClipAsset
{
    public bool loop = true;
    [HideInInspector]
    public TimelineClip clip;

    ClipCaps ITimelineClipAsset.clipCaps { get; }

    public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
    {
        var playable = ScriptPlayable<LoopBehaviour>.Create(graph);
        var clone = playable.GetBehaviour();

        clone.loop = loop;
        clone.clip = clip;

        return playable;
    }
}
```

```csharp
using UnityEngine.Timeline;

[TrackClipType(typeof(LoopClip))]
public class LoopTrack : TrackAsset
{
    protected override void OnCreateClip(TimelineClip clip)
    {
        var loopClip = clip.asset as LoopClip;
        loopClip.clip = clip;
    }
}
```

TrackAssetでは以下のようにしてClipを取得することもできる
```csharp
    protected override Playable CreatePlayable(PlayableGraph graph, GameObject gameObject, TimelineClip clip)
    {
        foreach (var clip in GetClips())
        {
            var loopClip = clip.asset as LoopClip;
            loopClip.clip = clip;
        }
        return base.CreatePlayable(graph, gameObject, clip);
    }
```

```csharp
    public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
    {
        foreach (var clip in GetClips())
        {
            var loopClip = clip.asset as LoopClip;
            loopClip.clip = clip;
        }
        return base.CreateTrackMixer(graph, go, inputCount);
    }
```