ゴマちゃんフロンティア

アザラシが大好きなエンジニアの開発日記です

【Unity】「n秒に1回実行」をなるべくスマートに組み込む方法を考えたお話

time 2020/08/07

今回はUnityに関するすごくちょっとしたお話です。
Unityで「n秒に1回」の処理を実装する場合、「Update()内でTime.deltaTimeを変数に加算or減算して判定」が一般的かと思います。

ただこの方法、以下の点から私はあまり好きではありません。

  • フィールドに加算or減算用の変数を設けなければならない
  • `Update()`内に変数への加算or減算と判定処理を書かなければならない

しかし「好きではありません」と言いながらこの方法しか思いつかないのも事実なので、せめて既存のクラスをあまり汚さずに実装できないか考えたお話です。
で、結論は身も蓋もないですが、「判定用のコンポーネントを作って使う側からメソッドを登録」になりました。

using System;
using UnityEngine;

public class IntervalExecutor : MonoBehaviour
{
    private Action executeAction;
    private bool executeFlag = false;
    
    private float elapsedTime = 0;
    private float intervalTime = 0;

    private void Update()
    {
        if (executeAction != null && executeFlag) {
            elapsedTime += Time.deltaTime;

            if (intervalTime <= elapsedTime) {
                elapsedTime = 0;
                executeAction();
            }
        }
    }

    public void Init(Action action, float intervalTime = 1f)
    {
        this.executeAction = action;
        this.intervalTime = intervalTime;
    }

    public void Play()
    {
        executeFlag = true;
    }

    public void Stop()
    {
        executeFlag = false;
    }
}

使う側はStart()内でAddComponent()し、実行したいメソッドを登録します。

using UnityEngine;

public class IntervalExecutorTest : MonoBehaviour
{
    private float count = 0;

    void Start()
    {
        var interval = 1f;
        var intervalExecutor = gameObject.AddComponent<IntervalExecutor>();

        intervalExecutor.Init(() => {
            count++;
            Debug.Log("アザラシ" + count);
        }, interval);
        intervalExecutor.Play();
    }
}

これでStart()内で完結できるので、使う側をあまり汚したくない場合はおすすめです。

down

コメントする