MRが楽しい

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

UniRxのSelectManyを使ってリストの要素やIObservableを返す

本日はUniRxの小ネタ枠です。
UniRxのSelectManyを使ってリストの要素やIObservableを返す方法を記事にします。

前提条件

UniRxの環境構築手順は以下の記事を参照ください。
bluebirdofoz.hatenablog.com

UniRxのSelectManyを使ってリストの要素やIObservableを返す

UniRxのSelectManyは大きく分けて2つの機能を提供します。

リストや配列を個別に返す

1つはリストや配列など値を返す際、それを個別に返す機能です。
以下にサンプルスクリプトを作成しました。それぞれSelectを利用するコードとSelectManyを利用するコードは同じログを出力します。
・UniRxSelectManyTest.cs

using UniRx;
using UnityEngine;
using UnityEngine.UI;

public class UniRxSelectManyTest : MonoBehaviour
{
    [SerializeField]
    private Button selectButton;

    [SerializeField]
    private Button selectManyButton;
    
    private void Start()
    {
        // 1, 2, 3を順番に出力する
        selectButton.OnClickAsObservable()
            .Select(_ => new[] { 1, 2, 3 })
            .Subscribe(list =>
            {
                foreach (var x in list)
                {
                    Debug.Log(x);
                }
            })
            .AddTo(this);
        
        // SelectManyを使って1, 2, 3を順番に出力する
        selectManyButton.OnClickAsObservable()
            .SelectMany(_ => new[] { 1, 2, 3 })
            .Subscribe(x => Debug.Log(x))
            .AddTo(this);
    }
}




Observableから新しいIObservableを返す

もう1つはObservableから新しいIObservableを返す機能です。
以下にサンプルスクリプトを作成しました。ボタン押下の通知を途中でIntarvalのIObservableに切り替えて値を流します。
・UniRxSelectManyTest2.cs

using System;
using UniRx;
using UnityEngine;
using UnityEngine.UI;

public class UniRxSelectManyTest2 : MonoBehaviour
{
    [SerializeField]
    private Button startButton;

    private void Start()
    {
        startButton.OnClickAsObservable()
            // ボタン押下時にログを出力する
            .Do(_ => Debug.Log($"ボタンが押されました"))
            .SelectMany(_ =>
            {
                var timerSec = 3.0f;
                return Observable.Interval(TimeSpan.FromSeconds(timerSec)).Select(count => (count+1)*timerSec);
            })
            // 以降はIntervalの通知を基にログを出力する
            .Subscribe(elapsedTime => Debug.Log($"{elapsedTime}秒前にボタンが押されました"));
    }
}