Unity::UniRx実装例メモ::ReactiveProperty.Subscribe()ケース別実装例::「普通のint変数の値を条件にUniRxコードでゲーム制御」など

コメント
今回のゲーム開発で使ったUniRxの実装例をメモしておこうと思います。ReactiveProPertyの使いこなしはUniRxでの実装実現の大きな一歩になるし、とにかく便利で読みやすいコードになるので、大プッシュしておきたいと思います^^ .Subscribe()はどういうときに使うのかわかりやすい記事を目指しました。
今回の例は、UniRxで、「単にint変数として活用できるようなReactivePropertyを単にテキスト表示してみる」と、「複数のスクリプトでひとつの変数(的オブジェクトのReactiveProperty)を参照し別々の出力をさせる(Subscribe)」と「普通のint変数の値によって条件づけをして、一定条件のときにのみReactivePropertyを発火させる」の実装例をご紹介します。
実際の実装後の動き
下記の実装例コードはこの自分で作ったゲームで実際に動いています^^「体力Scoreの表示」「エンディングシーン(変数定義したスクリプトのあるシーンとは別のシーン)でスコア表示」「タイマーが0になったらエンディングシーンへ遷移」がUniRxで実装しています。
コード解説::ReactivePropertyを条件づけしないでSubscribeだけ発火させる
この実装は「体力Scoreの表示」の部分です。
using UniRx;
using UniRx.Triggers;
using UnityEngine.UI;
public class ColliisionController : MonoBehaviour
{
//スコア表示させる部分
[SerializeField]
private Text _text;
//オプションつきのpivate int =10;と
//同じようなものだと思えば理解しやすい
ReactiveProperty<int> score = new ReactiveProperty<int>(10);
// Use this for initialization
void Start()
{
//.ToString()で文字列にして挿入
//_text.textで流し込める
//(_textではないところに注意)
score.Subscribe(x => _text.text = x.ToString()).AddTo(this);
コード解説::ほかのスクリプトのReactivePropertyを参照してSubscribe発火を実装
この実装は「エンディングシーン(変数定義したスクリプトのあるシーンとは別のシーン)でスコア表示」の部分です。
//ReactiveProperty<T>を設定したスクリプト
using UniRx;
using UniRx.Triggers; //いらないかも
using UnityEngine.UI;
public class GameMasterScript : MonoBehaviour {
public static ReactiveProperty<int> rp_gameScore = new ReactiveProperty<int>(0);
//↑要するに、public static int gameScore = 0;
//の代わりに設定するゲームスコアの値
↓
//Subscribeを発火させたい別のスクリプト@別シーンにアタッチしたもの
//スコア表示させる部分
[SerializeField]
private Text _text;
// Use this for initialization
void Start () {
//[スクリプト名(クラス名)].[変数名].Subscribe()で
//呼び出せる
GameMasterScript.rp_gameScore
.SubscribeToText(_text);
//↑そのまま値を文字列として流し込むメソッド
}
コード解説::Obserbableではない変数を条件にして、Subscribe発火させる
この実装は「タイマーが0になったらエンディングシーンへ遷移」の部分です。
using UniRx;
using UniRx.Triggers;
//↑※UpdateAsObservable()をつかうときは必要!
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class TimerController : MonoBehaviour {
public Text Timer;//タイマー
public static float Timer_sec = 120.0f;
//タイマーの持ち時間
void Start () {
//1行目:Update()と同じ感じの毎フレーム更新時作動
//だけど、ReactiveExtention機能つきの
//Upadate()みたいなもの
//2行目:Timer_sec(普通のfloat変数)<=0で
//時間切れになったら
//3行目:Endingシーンをロード
this.UpdateAsObservable()
.Where(_ => Timer_sec <= 0)
.Subscribe(_=>SceneManager.LoadScene("Ending"));
}
// Update is called once per frame
void Update () {
// 下記は普通のC#によるタイマーの設定、
//0秒を下回ったら持ち時間マイナスになると変なので
//0に固定する
if (Timer_sec >= 0)
{
Timer.text = Timer_sec.ToString("N2");
Timer_sec -= Time.deltaTime;
}
if (Timer_sec < 0)
{
Timer_sec = 0;
Timer.text = Timer_sec.ToString("N0");
}
}
}
こんな感じです^^