読者です 読者をやめる 読者になる 読者になる

vaguely

和歌山に戻りました。ふらふらと色々なものに手を出す毎日。

【Unity】Windows Store AppでUniRxのIObservableを使う

はじめに

ハマったのでメモ。

※今回の方法でとりあえず動作することは確認しましたが、正しい対処法かどうかは保証できませんのであしからず。

UniRxの一部のinterfaceは、.Net4.0以降のinterfaceと競合するものがあり、Windows Store App(以下WSA)用にビルドする場合にエラーとなる場合があります。

ここでは名前空間などを使用せずに、「UniRx.IObservable」なら「IObservable」としてね、とありました。

ところが、そのような方法をとっても「IObservable」が見つからないとエラーとなり、うまくビルドできませんでした(Unity5.5.0f3を使用)。

あれこれ試したところ、一応これでビルドができるようになりました。

.Net4.0との切り分け

まず.Net4.0の場合に、UniRxではなくSystem.IObservableが呼ばれるようにしてみます。

#if NETFX_CORE || NET_4_0
using System;
#endif

using UnityEngine;
using UniRx;
using UnityEngine.UI;

public class MainCtrl : MonoBehaviour
{
    public Button CompleteButton;
    private void Start ()
    {
        CompleteButton.onClick.AsObservable()
            .Subscribe(_ =>
            {
                // ボタンが押されたら一旦非表示.
                CompleteButton.gameObject.SetActive(false);
                ExecuteSomething().Subscribe(result => {},
                    () =>
                    {
                        // 一定時間経過後に再表示.
                        CompleteButton.gameObject.SetActive(true);
                    });
            });
    }
    private IObservable ExecuteSomething()
    {
        return Observable.Create(observer =>
        {
            Observable.Timer(System.TimeSpan.FromSeconds(2d))
                .Subscribe(tim => { }, () =>
                {
                    observer.OnNext(0);
                    observer.OnCompleted();
                });
            return new CompositeDisposable();
        });
    }
}
  • 「using System;」を分けているのは、「IObservable」の競合を避けるためです。

2017.01.31 7.21更新
ExcecuteSomethingの処理をNETFX_CORE、.Net4.0用に分けて書いていましたが、
内容が全く同じ(実行時に「UniRx.IObservable」と「System.IObservable」が自動で切り替わる)なため削除しました。

ただし、これだけだとまだエラーが発生していました。

で、あれこれ探っていたところ、下記のページを見つけました。

ここの中で、UniRxの「IObservable」を、「NETFX_CORE」環境では除外する提案がされています。
もしや…と思い、Assets/Plugins/UniRx/Scripts/System/IObservable.csを下記のように変更してみました。

IObservable.cs

// defined from .NET Framework 4.0 and NETFX_CORE

using System;

#if !(NETFX_CORE || ENABLE_MONO_BLEEDING_EDGE_EDITOR || ENABLE_MONO_BLEEDING_EDGE_STANDALONE
 || NET_4_0)

namespace UniRx
~省略~
  • 赤字の部分を追加しました。

おわりに

これでエラーが無くなり、無事ビルドすることができるようになりました。

ただしREADMEの内容を私が読み違えている恐れがあるため、これが正しい対処法かどうかは、分からない、という不安は残っています。

今後Unityが.Net4.0以上に対応するときには、この辺の問題も解決済みかもしれませんが、まぁ何かの役に立てば、ということでここに書き残しておきます。

参考