Unityで遅延実行を操作する方法
こんにちは!ジェイです。Unityでゲーム開発をしていると、任意のタイミングで送らせて、処理を実行したい時があります。そんな時に使う方法を解説します。
目次
Unity標準機能を使う場合
処理をn秒後に実行したい
private void Start()
{
//SomthingMethodを1.5秒後に呼び出す
Invoke("SomthingMethod", 1.5f);
}
void SomthingMethod()
{
Debug.Log("SomthingMethod");
}
Invokeの第1引数にメソッド名を第2引数にn秒後に実行するnを入れます。ただメソッドに引数を渡すことができないので、使い勝手はそこまで良く無いです。
private void Start()
{
//1.5秒後に実行する
StartCoroutine(SomthingMethod(1.5f, () =>
{
Debug.Log("Delay call");
}));
}
/// 渡された処理を指定時間後に実行する
private IEnumerator SomthingMethod(float waitTime, Action action)
{
yield return new WaitForSeconds(waitTime);
action();
}
コルーチンとWaitForSecondsを組み合わせてあげるパターンです。こちらだと引数も渡せるし便利です。
nフレーム後に実行したい
コルーチンを使う
private void Start()
{
//5フレーム後に実行する
StartCoroutine(SomthingMethod(5, () =>
{
Debug.Log("Delay call");
}));
}
// 渡された処理を指定時間後に実行する
private IEnumerator SomthingMethod(int delayFrameCount, Action action)
{
for (var i = 0; i < delayFrameCount; i++)
{
yield return null;
}
action();
}
秒数ではなくフレーム数だけ待つパターンです。
UniRxを使う場合
n秒後に実行したい
Observable.Timerを使う
//ただ呼び出すパターン
//100ミリ秒後にLogを出す
Observable.Timer(TimeSpan.FromMilliseconds(100))
.Subscribe(_ => Debug.Log("Delay call"));
//パラメータを渡すパターン
//現在のプレイヤの座標を500ミリ秒後に表示する
var playerPosition = transform.position;
Observable.Timer(TimeSpan.FromMilliseconds(500))
.Subscribe(_ => Debug.Log("Player Position:" + playerPosition));
Delayを使う
/ただ呼び出すパターン
//100ミリ秒後にLogを出す
Observable.Return(Unit.Default)
.Delay(TimeSpan.FromMilliseconds(100))
.Subscribe(_ => Debug.Log("Delay call"));
//パラメータを渡すパターン
//現在のプレイヤの座標を500ミリ秒後に表示する
Observable.Return(transform.position)
.Delay(TimeSpan.FromMilliseconds(500))
.Subscribe(p => Debug.Log("Player Position:" + p));
複数パラメータ渡したい場合はUniRx.Tupleを使うとできます。
nフレーム後に実行したい
Observable.TimerFrameを使う
//次のフレームで実行する
Observable.TimerFrame(1)
.Subscribe(_ => Debug.Log("Next Update"));
//次のFixedUpdateで実行する
Observable.TimerFrame(1,FrameCountType.FixedUpdate)
.Subscribe(_ => Debug.Log("Next FixedUpdate"));
DelayFrameを使う
//次のフレームで実行する
Observable.Return(Unit.Default)
.DelayFrame(1)
.Subscribe(_ => Debug.Log("Next Update"));
//次のFixedUpdateで実行する
Observable.Return(Unit.Default)
.DelayFrame(1, FrameCountType.FixedUpdate)
.Subscribe(_ => Debug.Log("Next FixedUpdate"));
次のフレームで実行する
//次のフレームで実行する
Observable.NextFrame()
.Subscribe(_ => Debug.Log("Next Frame"));
まとめ
単純に遅延処理を実行したいだけなら、コルーチンがよいです。遅延実行後に色々と処理をさせたい場合には、UniRXを使うとよいでしょう。
アイコンはりんご飴さんからお借りしました。
+5