ハツェの真時代傾向璋

興味を持ったことを書いていく鱗片的な場所から先の未来の場

一定間隔で処理をするやつの正攻法と裏技

こんばんは。ハツェです。
今回はミニtipsみたいなお話です。
SDK2時代のOnTimerをUdonならどう実装するかみたいな話です。
動作環境は、Unity : 2019.4.30f1、VRCSDK : 2021.09.03.09.25、U# : v0.20.3です。

目次


今回の概要

一定間隔で処理を行う方法の一例を紹介します。
参考程度に見てもらえればと思います。

通常の例

だいたい「Unity 一定間隔」とかで検索すると、Updateで時間ごとに処理を走らせるコードが出てくると思います。

[SerializeField] private float _timeInterval;
private float _timeElapsed;

private void Update()
{
    _timeElapsed += Time.deltaTime;
    
    if (_timeElapsed  > _timeInterval)
    {
        /*-- 一定間隔で実行したい処理 --*/

        // 経過時間を元に戻す
        _timeElapsed = 0f;
    }
}

これ自体はよくある実装例であり、かつ単純なコードで済みます。

DelayedSecondsを使った例

一方で、コルーチンを使った方法というのもまたUnityに存在しています。
ですが、Udonではコルーチンを使うことは現状出来ません。
しかし、SendCustomEventDelayedSecondsを使うことで似たようなことが出来ます。

[SerializeField] private float _timeInterval;

private void Start()
{
    DoFuction();
}

public void DoFuction()
{
    /*-- 一定間隔で実行したい処理 --*/

    if (_timeInterval > 0)
    {
        SendCustomEventDelayedSeconds(nameof(DoFuction), _timeInterval);
    }
}

この方法を使うことで、Updateの毎フレーム処理を軽減することが出来ます。
しかし、SendCustomEventDelayedSecondsは中断機能などを備えていないため、一度実行させてしまったら、対象の関数は絶対実行されます。
なので、やっぱり途中でやめる!みたいなものを追加したい場合は、if文に条件を加えたりする必要があると思います。

あとがき

今回は、SendCustomEventDelayedSecondsを使ったOnTimer代替実装を紹介しました。
おそらく非同期実装だと思っているので、複雑なものを実装するときは少し躊躇するかなとも思っています。
他の方法としては過去に、Sphereをバウンドさせ、着地した時に処理を走らせることで、一定間隔ごとに処理を行わせるみたいなテクニックもありました。
それ以外にも面白い方法とかありましたら、是非ともコメントにて教えて頂けると記事ネタにもなるので助かります。
以上です!ありがとうございました。