UniRxを勉強しよう5

はい。なんか前日に書いた内容が投稿できずに終わっていることが多い。多分眠くて公開するのを忘れていたのだろう…
今回は前回作成したOnNextで発されたメッセージを取得するクラスから、GUI上のディスプレイに数値を表示させてみたいと思う。

出来上がったものがこちらです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UniRx;
using UnityEngine.UI;

public class ShowDisplay : MonoBehaviour
{
    //メッセージのやりとり対象はInspector画面から設定する。
    public Text displayPanelText;
    [SerializeField] private PassPushedButton passPushedButton;

    // Start is called before the first frame update
    void Start()

    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    void Awake()
    {
        //監視対象スクリプトからOnNextが飛んで来たら下記Subscribe処理を実行
        passPushedButton.KeyClicked
            .Scan((pre, current) => pre + current)
            .Subscribe(KeyCode => ShowToDisPlay(KeyCode));
    }

    private void ShowToDisPlay(string value)
    {
        if(value.Substring(0,1) == "0")
        {
            value = value.Substring(1, value.Length - 1);
        }
        displayPanelText.text = value;
    }
}

画面は以下のような感じだ。

f:id:dkkng:20200720233132p:plain
入力値が画面に表示されている。これだけで大分それっぽいな

最初に0が入力されていた場合はそれを消した文字列を取得するようにしている。
今の状態だと「+」「÷」といった記号類もここに表示してしまうため、それが入力された場合の処理を別途記入する必要がある。

これについてもif文の中でやってもよいのだが、せっかくなので演算記号は別途Subjectでイベントを取得するようにしてみようと思う。まあ基本的に前回書いた処理の焼き直しなのでそんなに難しくない。

演算記号用に書いてみよう

まずボタンの押下を検知するクラス。
数値(小数点含む)を押した場合と演算記号を押した場合とで別のSubjectからOnNextが発される。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UniRx;
using System;
using UnityEngine.UI;
using System.Security.Cryptography.X509Certificates;
using System.Threading;

public class PassPushedButton : MonoBehaviour
{
    [SerializeField] List<Button> buttons;
    [SerializeField] List<Button> operaterKeys;
    [SerializeField] List<Text> texts;


    //このクラスからOnNextで別クラスに処理を渡せるようSubjectを用意
    private Subject<string> sendCalcSubject = new Subject<string>();
    private Subject<int> sendOperaterSubject = new Subject<int>();

    //なんだっけこれ…プロパティ?外部クラスからアクセス(getのみ)できるようにしておく
    public IObservable<string> KeyClicked
    {
        get { return sendCalcSubject; }
    }

    public IObservable<int> OperaterKeyClicked
    {
        get { return sendOperaterSubject; }
    }

    // Start is called before the first frame update
    void Start()
    {


    }

    // Update is called once per frame
    void Update()
    {

    }

    void Awake()
    {
        for (int i = 0; i < buttons.Count; i++)
        {
            ButtonCheck(i);
        }
        for(int i =0; i < operaterKeys.Count; i++)
        {
            OperatorKeyChecked(i);
        }
    }

    void ButtonCheck(int i)
    {
        buttons[i].onClick.AsObservable()
            .Subscribe(count =>
            {
                //定義したSubjectからOnNextでメッセージを出す
                sendCalcSubject.OnNext(texts[i].text);
            })
            .AddTo(gameObject);
    }

    void OperatorKeyChecked(int i)
    {
        operaterKeys[i].onClick.AsObservable()
            .Subscribe(count =>
            {
                sendOperaterSubject.OnNext(i);
            })
            .AddTo(gameObject);
    }
}

そしてそれを受けてディスプレイの表示を変更するクラスがこちら

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UniRx;
using UnityEngine.UI;

public class ShowDisplay : MonoBehaviour
{
    //メッセージのやりとり対象はInspector画面から設定する。
    public Text displayPanelText;
    [SerializeField] private PassPushedButton passPushedButton;

    // Start is called before the first frame update
    void Start()

    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    void Awake()
    {
        //監視対象スクリプトからOnNextが飛んで来たら下記Subscribe処理を実行
        passPushedButton.KeyClicked
            //.Scan((pre, current) => pre + current)
            .Subscribe(KeyCode => ShowToDisPlay(KeyCode))
            .AddTo(gameObject);
        passPushedButton.OperaterKeyClicked
            .Subscribe(a => 
            {
                ShowToDisPlay("");
            })
            .AddTo(gameObject);
    }

    private void ShowToDisPlay(string value)
    {
        if(value == "")
        {
            displayPanelText.text = "";
        }
        else
        {
            displayPanelText.text += value;
        }
    }
}

この時点だとさっきまでできていた「一番最初の0は削除する」の機能が失われているし、小数点が入力された場合の動作にも対応していないが、一旦今日はここまでとしたい。
早いところ演算処理に移りたい...それはそれで別のクラスで作っていく予定だ。
それでは、今回はここまで。