MRが楽しい

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

UniRxのMergeを使って複数のボタンに同じ処理を設定する

本日は UniRx の小ネタ枠です。
UniRxのMergeを使って複数のボタンに同じ処理を設定する方法を記事にします。

UniRxのMergeを使って複数のボタンに同じ処理を設定する

UniRx の Merge オペレータを使うことで複数の Observable に対してまとめて購読を行えます。
Button のクリックイベントを Observable に変換する OnClickAsObservable を組み合わせて利用することで、複数のボタンにまとめて同じ処理を設定することができます。

サンプルスクリプト

以下の2つのボタンのクリックイベントに対してログ出力の処理を設定するサンプルスクリプトを作成しました。
・ListMergeTest.cs

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using UniRx;
using UnityEngine;
using UnityEngine.UI;

public class ListMergeTest : MonoBehaviour
{
    [SerializeField]
    private Button firstButton;

    [SerializeField]
    private Button secondButton;

    void Start()
    {
        List<Button> buttons = new List<Button>()
        {
            firstButton,
            secondButton,
        };

        buttons
            .Select(button => button.OnClickAsObservable()) // ボタンのクリックイベントをIObservableに変換
            .Merge() // リストの全てのIObservableをマージ
            .Subscribe(_ => // 全てのIObservableに対してログ出力のイベントを購読する
            {
                Debug.Log("Button Clicked !!");
            })
            .AddTo(this);
    }
}

以下のサンプルシーンを用意して Inspector で2つの Button コンポーネントの参照を設定しました。

シーンを再生して動作を確認します。

どちらのボタンを押下しても同じ処理が実行され、ログが表示されました。

リストのインデックスを取得する

以下の記事で解説した Select オペレータでインデックスを取得する方法を利用すると、以下の通り、同じ処理の中でインデックスを参照できます。
bluebirdofoz.hatenablog.com

・ListMergeTest02.cs

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using UniRx;
using UnityEngine;
using UnityEngine.UI;

public class ListMergeTest02 : MonoBehaviour
{
    [SerializeField]
    private Button firstButton;

    [SerializeField]
    private Button secondButton;

    void Start()
    {
        List<Button> buttons = new List<Button>()
        {
            firstButton,
            secondButton,
        };

        buttons
            .Select(button => button.OnClickAsObservable()) // ボタンのクリックイベントをIObservableに変換
            .Merge() // リストの全てのIObservableをマージ
            .Select((unit, index) => index) // リストのインデックスを取得
            .Subscribe(index => // 全てのIObservableに対してログ出力のイベントを購読する
            {
                Debug.Log($"{index} Button Clicked !!");
            })
            .AddTo(this);
    }
}