MRが楽しい

MRやVRについて学習したことを書き残す

UniRxを使って一定フレーム毎に同一フレームで発生したUnityのイベントをまとめて処理する

本日は UniRx の小ネタ枠です。
UniRxを使って一定フレーム毎に同一フレームで発生したUnityのイベントをまとめて処理する方法を記事にします。
f:id:bluebirdofoz:20210415161420j:plain

OnTriggerStayAsObservable

今回利用する OnTriggerStayAsObservable は Collider の OnTriggerStay イベントを Observable に変換します。
UniRx の ObservableTriggers を利用すると、他にも様々な Unity イベントを Observable に変換することができます。

サンプルコード

以下のようなサンプルコードを作成しました。
100 フレームに一度、同一フレームで検出した collider をリストにまとめて通知します。
・TestOnTriggerStayAsObservable.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UniRx;
using UniRx.Triggers;

namespace HMProject.Test
{
    public class TestOnTriggerStayAsObservable : MonoBehaviour
    {
        // Start is called before the first frame update
        void Start()
        {
            this.OnTriggerStayAsObservable()   // OnTriggerStayイベント
                .BatchFrame()                  // フレーム毎に値をまとめる
                .ThrottleFirstFrame(100)       // 100フレーム毎に結果を取得する
                .Subscribe(colliderlist =>
                {
                    Debug.Log("collider count : " + colliderlist.Count);
                    foreach (Collider collider in colliderlist)
                    {
                        int frameCount = Time.frameCount;
                        Debug.Log("Stay GameObject : " + collider.gameObject.name + ", FrameCount : " + frameCount.ToString());
                    }
                })
                .AddTo(this);
        }
    }
}

f:id:bluebirdofoz:20210415161332j:plain

以下のオペレータを利用してメッセージをフィルタリングしています。

BatchFrame

指定したフレーム数の間に発行されたメッセージを1つにまとめるオペレータです。
フレーム数のカウントはメッセージを受け取ったタイミングで開始されます。
引数を指定しない場合、同一フレームのメッセージをまとめます。フレーム数は 0 オリジンです。

ThrottleFirstFrame

メッセージを受け取った後、指定フレームの間、次のメッセージを通さないオペレータです。
時間で指定する ThrottleFirst というオペレータもあります。

このスクリプトをオブジェクトを検出する Collider を設定したオブジェクトに追加します。
f:id:bluebirdofoz:20210415161344j:plain

動作確認

シーンを再生して動作を確認します。
ログを確認すると、一定のフレーム間隔で、同一フレームに検出したコライダーの情報が取得できていることがわかります。
f:id:bluebirdofoz:20210415161355j:plain