UniRxを勉強しよう3
UniRxを使って電卓を作る、三日目だ。
昨日でUniRxを使ってイベントを取得する方法が分かってきたので、今日はロードマップの3の部分を進めようと思う
1. まずは簡単に見た目だけ作る
2. ボタンを押下した際にこれを検知する
3. 押下されたボタンから数値や記号を取得する
4. 引数に渡された数値がディスプレイに表示されるようにする
5. 検知した数値や記号から四則演算を実施できるようにする
6. 見てくれを整える
7. 書き出す
なんとなく飛ばしていたSerializeFieldが問題になった
ボタンを押した際、押された値を取得する処理を実装するにあたってつまづいた…
僕としてはボタンを配列(正確にはList)にポコポコと放り込む形がコード上はきれいかなと思ったのだが、SerializeFieldがなんだか分からないため扱いに困ってしばらく悩んだ。
調べたところ、「Inspectorに変数(等)を表示させたいけど、publicで表示させると不都合が起こるので使う」的なものらしい。特に変数の定義自体に影響はない。
ので以下のように書いて解決した。
[SerializeField] List<Button> button = new List<Button>();
これでインスペクターから要素数も指定できるし、複数のボタンをリストで使えるようになった。
さて、ここでUnity側で通常のエディタとしてVisualStudio2019に設定するのを忘れていたことに気付いた。設定をしてみると、UniRxに関する予測変換が利いていないことが判明。なんなの?
しばらく色々試したが、最終的にこの記事が見つかった。
raspberly.hateblo.jp
「using UniRxがうまくいかないぞ」という人はぜひ見てほしい。
でもこの通りにやってもAsObservableで赤い波線が出てしまう。ほんとやだ。
そのあと色々試したが、結局上手くいかないのでもう無視する。エディタークソ。
気を取り直して
ようやく本題に入れた…下記の通りに書き直して押されたボタンが何かを特定できるようになった。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UniRx; using System; using UnityEngine.UI; public class PassPushedButton : MonoBehaviour { [SerializeField] List<Button> buttons; [SerializeField] List<Text> texts; // 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); } } void ButtonCheck(int i) { //Debug.Log(texts[i]); buttons[i].onClick.AsObservable() .Select(_ => 1) .Scan(0, (element, aba) => element + aba) .Subscribe(count => { Debug.Log(texts[i].text); }) .AddTo(gameObject); } }
とりあえずどのボタンが押されたか検知させることはできるようになった。
頭の中の設計では、このPassPushedButtonは「Pass」と言っている通り、別に作成する計算用のクラスに押されたボタンとその値を通知する仕組みにする。なんかその方がすっきりしません?
そっちのクラスに四則演算の処理を書いておく。
一旦ここまでにしよう…本分じゃない部分でずいぶん時間を食わされた…
【参考にしたサイト】
qiita.com