初期化処理の完了待ちを行ったり、途中のロード完了を待ち受けたい時に
タイムラインでどうやって実装したら良いかわからなかったので調査してみました。
参考URL:
https://blogs.unity3d.com/jp/2018/04/05/creative-scripting-for-timeline/
https://github.com/UnityTechnologies/ATerribleKingdom
■前提
テスト用にUpdate文の中で数字を加算するだけの簡単な処理を作りました。
数値が1000を超えるとFLGがTrueになり、Trueになるとタイムライン側のループをやめて
次のクリップの処理に移行するようにしました。
(Update文内の処理はかなり雑)
■処理
数値が1000を超えるまではCubeが表示され、それ以降はSphereが表示されるという簡単なものです。
■Playble Assetが参照しているオブジェクトにあたっちされているソース
using UnityEngine;
public class FlgChange : MonoBehaviour
{
public bool IsEnd = false;
int count = 0;
// Start is called before the first frame update
void Start()
{
IsEnd = false;
count = 0;
}
// Update is called once per frame
void Update()
{
count++;
Debug.Log("count=" + count);
if(count > 1000)
{
Debug.Log("IsEnd=" + IsEnd);
IsEnd = true;
}
}
}
■Playble Asset
using UnityEngine;
using UnityEngine.Playables;
[System.Serializable]
public class TestWaitAsset : PlayableAsset
{
public ExposedReference<FlgChange> FlgChangeValue;
// Factory method that generates a playable based on this asset
public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
{
Debug.LogError("CreatePlayable");
var testPlayable = ScriptPlayable<TestWaitBehaviour>.Create(graph);
var testBehaviour = testPlayable.GetBehaviour();
testBehaviour.TestFlgChange = FlgChangeValue.Resolve(graph.GetResolver());
return testPlayable;
}
}
下記の時間を巻き戻す処理でタイムラインの初めまで戻します、
数値指定すればそこに戻るはず。
おそらくフレーム単位の形でも時間単位の形でも戻すことも可能なはず(調べてません。)
// 時間を巻き戻す
(playable.GetGraph().GetResolver() as PlayableDirector).time = 0.00d;
■Playable Behaviour
using UnityEngine;
using UnityEngine.Playables;
// A behaviour that is attached to a playable
public class TestWaitBehaviour : PlayableBehaviour
{
public FlgChange TestFlgChange;
private bool clipStart = false;
// Called when the owning graph starts playing
public override void OnGraphStart(Playable playable)
{
clipStart = false;
}
// Called when the owning graph stops playing
public override void OnGraphStop(Playable playable)
{
}
// Called when the state of the playable is set to Play
public override void OnBehaviourPlay(Playable playable, FrameData info)
{
clipStart = true;
}
// Called when the state of the playable is set to Paused
public override void OnBehaviourPause(Playable playable, FrameData info)
{
if(playable.IsNull())
{
return;
}
Debug.LogError("IsEndLoop=" + TestFlgChange.IsEnd);
Debug.LogError("clipStart=" + clipStart);
if(clipStart)
{
if(!TestFlgChange.IsEnd)
{
// 時間を巻き戻す
(playable.GetGraph().GetResolver() as PlayableDirector).time = 0.00d;
}
}
}
// Called each frame while the state is set to Play
public override void PrepareFrame(Playable playable, FrameData info)
{
}
}