ObservableのMergeオペレータがかなり便利だと思ったので突発的に記事を書いてみました。
とりあえずサンプルコード
YesかNoのどちらかを選択するダイアログをイメージしてください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UniRx;
using System;
using UniRx.Operators;
/// <summary>
/// ストリームのマージサンプル
/// </summary>
public class MergeStreamSample : MonoBehaviour
{
/// <summary>
/// Yesボタン
/// </summary>
[SerializeField]
private Button YesButton = null;
/// <summary>
/// Noボタン
/// </summary>
[SerializeField]
private Button NoButton = null;
/// <summary>
/// Yesボタンが押された
/// </summary>
private IObservable<Unit> OnSelectedYes { get { return YesButton.OnClickAsObservable(); } }
/// <summary>
/// Noボタンが押された
/// </summary>
private IObservable<Unit> OnSelectedNo { get { return NoButton.OnClickAsObservable(); } }
/// <summary>
/// 何かが選択された
/// </summary>
private IObservable<bool> OnSelectedAny
{
get
{
return OnSelectedYes
.Select((_) => true)
.Merge(
OnSelectedNo
.Select((_) => false)
);
}
}
void Awake()
{
// 特に加工されていないストリームのSubscribe
OnSelectedYes.Subscribe((_) => Debug.Log("YES")).AddTo(gameObject);
OnSelectedNo.Subscribe((_) => Debug.Log("NO")).AddTo(gameObject);
// MergeされたストリームのSubscribe
OnSelectedAny
.Where((b) => b)
.Subscribe((_) => Debug.Log("Merge YES"))
.AddTo(gameObject);
OnSelectedAny
.Where((b) => !b)
.Subscribe((_) => Debug.Log("Merge NO"))
.AddTo(gameObject);
OnSelectedAny
.Subscribe((b) => Debug.Log("b:" + b))
.AddTo(gameObject);
}
}
OnSelectedAnyプロパティが行っている事
- OnSelectedYesの型をUnitからboolに変換してtrueを流す
- OnSelectedNoの型をUnitからboolに変換してfalseを流す
- 上記で作ったストリームを合成し、Yesボタンが押されたらtrueが、Noボタンが押されたらfalseが流れてくるストリームの完成
所感
「どちらが選択されても共通の処理を行う」という場合に便利だと思います。
Subject<bool>
を定義してボタンイベントで発火させるという手段でも同じ結果が得られると思いますが、こちらの方がシンプルなコードになる気がします。