2016/01/01

UniRxでUnityWebRequest

UnityのWWWに代わる新しいUnityWebRequestが5.3で実プラットフォームで使えるようになったので、いつもの如くRxにしようとしたら、まだUniRxにラップしたクラスがなかったので、勉強がてら作ってみました。
といっても、neueccさんご本人がIssueを立てられているので、公式でもすぐサポートされると思いますが、そこはそれ。

流れとしては、UniRxにはCoroutineをObservableに変換するObservable.FromCoroutineがあるので、UnityWebRequestオブジェクトをいい感じにCoroutineにして、これをObservableに変換します。というか、ObservableWWWをベースにUnityWebRequestに合わせて修正したものを、UnityWebRequestのメソッドと引数に合わせてラップしていくだけです。

UnityWebRequestの基本的なCoroutineはこんな感じです。
using System.Collections;
using UnityEngine;
using UnityEngine.Experimental.Networking;
public class UnityWebRequestUsage : MonoBehaviour
{
void Start()
{
StartCoroutine(GetText());
}
IEnumerator GetText()
{
using (UnityWebRequest request = UnityWebRequest.Get("http://unity3d.com/"))
{
yield return request.Send();
if (request.isError) // Error
{
Debug.Log(request.error);
}
else // Success
{
Debug.Log(request.downloadHandler.text);
}
}
}
}
UnityWebRequest.Getはファクトリーメソッドで、これにurlほかの引数を与えるとUnityWebRequestオブジェクトが返ってくるので、Sendメソッドを実行してyield returnで待ち、結果をisErrorプロパティで判別して、成功ならdownloadHandlerプロパティにアタッチされているDownloadHandlerへの参照が入っているので(ファクトリーメソッドによる)、ここからダウンロードされたものを取得します。

ファクトリーメソッドはGetのほか、Post、Put、Delete、HeadでRESTをカバーしていて、基本のGet以外にTexture用のGetTextureとAssetBundle用のGetAssetBundleもあります。実行はすべてSendで行われ、WWWのようにコンストラクト即実行とは違います。これに引っ掛かって少し悩みました。

これと同じことを、作成したObservableWebRequestでやるとこんな感じです。
using UnityEngine;
using UniRx;
public class ObservableWebRequestUsage : MonoBehaviour
{
void Start()
{
ObservableWebRequest.Get("http://unity3d.com/")
.Subscribe(
x => Debug.Log(x), // Success
ex => Debug.LogException(ex)); // Error
}
}
ObservableWWWとクラス名が違うだけでした。

基本的なテストは基本のGetで確認しましたが、他はこれからです。といっても、UnityWebRequestは標準で使う限りシンプルなので、間違える要素は少ないと思いますが。

0 コメント :