Unityでの簡易タイマーイベント制作

2023年3月24日

Unityでの時間の扱いは、Time.deltaTimeの加算を使った方法、コルーチン、Taskなどを使った方法があります
しかし、単純なタイマーであれば、イベントを組み合わせることで実現することができます

サンプルシーン

空のゲームオブジェクトを1つ作成し、2つのスクリプトをアタッチします

DelayTimerがイベントで、TestスクリプトのShowメソッドを登録すると、一定時間間隔(Span)ごとに実行されることになります

スクリプト

遅延タイマーイベント

一定時間ごとにイベントハンドラ(メソッド)が実行されるイベントになります

using UnityEngine;
using UnityEngine.Events;

public class DelayTimer : MonoBehaviour
{
    public UnityEvent delayTimerEvent;

    [Header("間隔(秒)")]
    public float span;

    float delay;

    void Update()
    {
        delay += Time.deltaTime;

        if (delay > span)
        {
            delayTimerEvent.Invoke();
            delay = 0;
        }
    }
}

Time.deltaTimeの足し込みを使って一定時間に到達したかチェックしています
この仕組みの詳細については省略します

public UnityEvent delayTimerEvent;

これにより、インスペクターでイベントハンドラの登録設定ができるようになります

イベントハンドラ

イベントが発生したら実行されるイベントハンドラ(メソッド)のサンプルです

using UnityEngine;

public class Test : MonoBehaviour
{
    public void Show()
    {
        Debug.Log("タイマーイベント!");
    }
}

スクリプトのアタッチ

2つのスクリプトをGameObjectオブジェクトにアタッチします

タイマーイベントを発生させる間隔の登録、また、実行するイベントハンドラの登録を行います

ヒエラルキービューからドラッグ&ドロップしてもいいですし、また、キャプチャのようにスクリプトをドラッグ&ドロップしてもOKです

続いてプルダウンメニューからイベントハンドラ(今回は、Showメソッド)を登録して完了です

おまけ

実は、上記の仕組みは次のコード1つで実現できます
では、なぜややこしいイベントの仕組みを考えるのでしょうか?

using UnityEngine;

public class DelayTimer : MonoBehaviour
{
    [Header("間隔(秒)")]
    public float span;

    float delay;

    void Update()
    {
        delay += Time.deltaTime;

        if (delay > span)
        {
            Debug.Log("タイマーイベント!");
        }
    }
}

一時的にタイマーを使う場合

上記のシンプルなコードで十分です
わざわざ、イベントを使うまでもありませんね

タイマーイベントの追加や変更をしたい場合(ゲーム中含む)

例えば、タイマーイベントで他の違うメソッド(イベントハンドラ)も実行するように仕様追加したい、また、そのメソッドは他のゲームオブジェクトにアタッチされている、などなど

どんどん、シンプルだったメソッドが膨れ上がってきますよね
GameObject.FindメソッドやGetComponentメソッドも追加しなくてはならないですし、またそれを変更したいなんてことになったら、行き当たりばったりで修正すると厄介なことになりますね

このようなことが想定されるときにUnityEventを併用するといいでしょう

Unity

Posted by hidepon