アマゾンバナーリンク

ディスプレイ広告

スポンサーリンク

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