はじめに
Unityで開発している時にマルチシーンエディティングを利用しているケースは多いと思います。
その際にシーン間でパラメーターを渡す方法で悩む人が多いと思います。
今回はそんな場合に、UniRxのMessageBrokerが便利だと思ったので紹介したい思います。
環境
- Unity 2021.1.16f1
 - UniRx 7.1.0
 
変更前の方法
マルチシーンエディティングの際にパラメーターを渡す方法はいくつかあると思いますが、まずはstaticクラスを利用した場合でのサンプルです。
MenuSceneController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MenuSceneController : MonoBehaviour
{
    [SerializeField] private Text coinText;
    // Start is called before the first frame update
    void Start()
    {
        
    }
    // Update is called once per frame
    void Update()
    {
        if (coinText)
        {
            coinText.text = User.coin.ToString();
        }
    }
}
SampleSceneController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SampleSceneController : MonoBehaviour
{
    [SerializeField] private Button button;
    // Start is called before the first frame update
    void Start()
    {
        button.onClick.AddListener(OnClickedButton);
    }
    private void OnClickedButton()
    {
        User.coin += 10;
    }
}
User.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class User
{
    public static int coin = 0;
}

上記のサンプルではSampleSceneにあるボタンを押すと静的クラスであるUserクラスのコインを加算します。
その後、MenuScene内のUpdateの処理により画面上の数値が更新されるというものです。
これでも動作上問題ないですが、MenuSceneのUpdateが常に走り続けるのが少し気になります。
変更後
ではUniRxのMessageBrokerを使った場合のサンプルです。
MessabeBrokerでは任意のクラスを自分のタイミングで受け渡しする事ができます。
MenuSceneController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UniRx;
public class MenuSceneController : MonoBehaviour
{
    [SerializeField] private Text coinText;
    // Start is called before the first frame update
    void Start()
    {
        coinText.text = "0";
        MessageBroker.Default.Receive<User>().Subscribe((user) => {
            if (coinText)
            {
                coinText.text = user.coin.ToString();
            }
        });
    }
}
SampleSceneController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UniRx;
public class SampleSceneController : MonoBehaviour
{
    [SerializeField] private Button button;
    private int coin = 0;
    // Start is called before the first frame update
    void Start()
    {
        button.onClick.AddListener(OnClickedButton);
    }
    private void OnClickedButton()
    {
        coin += 10;
        var user = new User(coin);
        MessageBroker.Default.Publish<User>(user);
    }
}
User.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class User
{
    public int coin;
    public User(int coin)
    {
        this.coin = coin;
    }
}

このサンプルもSampleSceneのボタンを押すとMenuSceneの表示が切り替わるものですが、決定的に違うのは静的クラスを使っていないことです。
さらにMenuSceneの表示の処理をUpdateを利用していないのですっきりと書くことが出来ます。
この機能程度のものならどのような書き方でも良いかも知れないですが、MenuSceneにアプリ内通知とかの機能をいれる場合はMessabeBrokerが相性が良いのではないかと個人的に思います。
さいごに
UniRxを使っていると便利以外の言葉が出てこない。
  
  
  
  




コメント