えんじにあ雑記!

開発していて学んだことをまとめていきます!

UniRxでReactivePropertyのSubscribeにラムダ式が使えない

f:id:flat-M_M:20200407225456j:plain

UniRxを使っている時「ラムダ式はデリゲート型ではないのでIObserverに変換できません」というエラーに遭遇!

チュートリアル通り使ってるのになんで!?と困ったことと、解決方法について。

内容

題名の通りで、UniRxのReactivePropertyのSubscribeメソッドにラムダ式で処理を登録したかったのですが、初めて触った時にエラーが出てしまったのでその対処法を記しておきます。

クラス構成

今回はModelクラスとViewクラスに分けて開発を行っている状況でした。そのため、以下の二つのスクリプトを作成しています。

まずは、乱数を生成して管理するモデルクラスであるRandomNumModel.csを作成します。

using UniRx;
using UnityEngine;

public class RandomNumModel
{
    public ReactiveProperty<int> randomNum;

    public RandomNumModel()
    {
        randomNum.Value = Random.Range(0, 100);
    }

    public void CalcRandomNum()
    {
        randomNum.Value = Random.Range(0, 100);
    }
}

次に、そのRandomNumModelクラスを使ってテキストへの表示処理を担うViewクラスReactivePropertyView.csを作成します。

using UnityEngine;
using UnityEngine.UI;

public class ReactivePropertyView : MonoBehaviour
{
    [SerializeField]
    private Text displayText;

    private RandomNumModel randomNumModel;

    private void Awake()
    {
        randomNumModel = new RandomNumModel();
    }

    private void Start()
    {
        randomNumModel.randomNum.Subscribe(num =>
        {
            displayText.text = num.ToString();
        });
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Return))
        {
            randomNumModel.CalcRandomNum();
        }
    }
}

実装したい処理としては、エンターを押した時にモデルクラスのメソッドを呼び出してモデルクラス内の数字データを変更し、変更された際にrandomNumを購読しているObserverに変更を通知し処理を実行する ということを目指していました。

エラー内容

エラー内容
エラー内容

「ん?ラムダ式使えないの?参考にしてるサイトなら使えてるのに…UniRxワカラン( ̄▽ ̄)」 って感じになってました

解決方法

using UniRx;

この一行だけ。クイック修正では候補に出なかったので見落としていたのですが、この宣言を書くのを忘れているだけでした。

もう少しこの原因を追ってみると下記の部分に拡張メソッドの実装がありました。 UniRxのSubscribeの拡張メソッド

基本的にはこれらの拡張メソッドを使ってSubscribeする方が簡潔にかけて良さそうですね。

まとめ

UniRxのReactivePropertyのSubscribeでラムダ式が使えない原因としては、そもそもラムダ式を使った記法は拡張メソッドで定義されており、それを使うための宣言が抜けていたからでした。

簡単なことだったのに…かなり時間使った( ◠‿◠ )