MRが楽しい

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

HoloLens2でホロモンアプリを作る その116(SubjectとIObservableを使ってボタン操作の監視用変数を公開する)

本日はアプリ作成枠です。
HoloLens2でホロモンアプリを作る進捗を書き留めていきます。
今回はSubjectとIObservableを使ってボタン操作の監視用変数を公開する修正を行いました。

SubjectとIObservableを使ってボタン操作の監視用変数を公開する

Subject は UniRx で利用可能な IObservable と IObserver を実装したクラスです。
本クラスを利用して値の変化を監視する IObservable を簡単に実装できます。

サンプルスクリプト

今回は以下のマニュアルウィンドウの閉じるボタンやページ送りボタンの押下を通知する仕組みを作成してみます。

それぞれのボタンの押下を通知する IObservable を作成し、public 変数からボタンの押下を監視できるようにしてみました。
・ItemManualWindowViewAccessor.cs

using System;
using Cysharp.Threading.Tasks;
using Microsoft.MixedReality.Toolkit.UI;
using UniRx;
using UnityEngine;
using UnityEngine.Serialization;

namespace HoloMonApp.Content.SupportItem.Objects.Windows.ManualWindow
{
    public class ItemManualWindowViewAccessor : MonoBehaviour, IItemApplyView
    {
        // ページ送りボタンの通知と監視
        private Subject<ItemManualWindowStatus> changeStatusEvent = new();
        public IObservable<ItemManualWindowStatus> ChangeStatusEvent => changeStatusEvent;

        // 閉じるボタンの通知と監視
        private Subject<Unit> closeEvent = new();
        public IObservable<Unit> CloseEvent => closeEvent;

        [SerializeField] private GameObject _holoMonRuleSlide;

        [SerializeField] private GameObject _manualSlide;

        [SerializeField] private Interactable _nextButton;
        
        [SerializeField] private Interactable _closeButton;

        void Start()
        {
            _nextButton.OnClick.AsObservable()
                .Subscribe(_ =>
                {
                    changeStatusEvent.OnNext(ItemManualWindowStatus.Manual);
                })
                .AddTo(this);

            _closeButton.OnClick.AsObservable()
                .Subscribe(_ =>
                {
                    closeEvent.OnNext(Unit.Default);
                })
                .AddTo(this);
        }

        public void ShowHoloMonRuleSlide()
        {
            _holoMonRuleSlide.SetActive(true);
            _manualSlide.SetActive(false);
        }
        
        public void ShowManualSlide()
        {
            _holoMonRuleSlide.SetActive(false);
            _manualSlide.SetActive(true);
        }
    }
}

監視する側で以下のように IObservable を購読することでボタン押下が発生したときの処理を記述することができます。
・ItemManualWindowAccessAPI.cs

using System;
using Cysharp.Threading.Tasks;
using UniRx;
using UnityEngine;
using UnityEngine.Serialization;

namespace HoloMonApp.Content.SupportItem.Objects.Windows.ManualWindow
{
    public class ItemManualWindowAccessAPI : ItemWindowAccessAPI
    {
        [SerializeField] private ItemManualWindowStatus _itemManualWindowStatus;
        public ItemManualWindowStatus Status => _itemManualWindowStatus;

        [SerializeField] private ItemManualWindowStatusChanger _itemManualWindowStatusChanger;
        
        [SerializeField] private ItemManualWindowBehaveController _itemManualWindowBehaveController;

        [SerializeField] private ItemManualWindowViewAccessor _itemManualWindowViewAccessor;

        private void Start()
        {
            // 各ボタン押下時の処理をここで定義する
            _itemManualWindowViewAccessor.ChangeStatusEvent
                .Subscribe(_itemManualWindowStatusChanger.ChangeStatus)
                .AddTo(this);

            _itemManualWindowViewAccessor.CloseEvent
                .Subscribe(_ => DestroyObject())
                .AddTo(this);
        }

        public virtual void SpawnObject()
        {
            base.SpawnObject();
            
            _itemManualWindowStatusChanger.ChangeStatus(ItemManualWindowStatus.HoloMonRule);
        }

        public void ChangeStatus(ItemManualWindowStatus status)
        {
            _itemManualWindowStatusChanger.ChangeStatus(status);
        }
    }
}