LoginSignup
13
7

More than 3 years have passed since last update.

Unity2018.3以降でObservableWWWの代替手段

Last updated at Posted at 2019-07-22

ObservableWWW

ObservableWWWとはUniRxでUnityEngine.WWWObservableとして扱える便利な機構でした。
ですがこのUnityEngine.WWW自体がかなり古く、2019年現在では非推奨となってしまいました。
(代わりにUnityWebRequestを使う必要がある)

それに伴い、Unity2018.3以降ではObservableWWWObsoleteになってしまいました。

1.jpg

そこで今回は、Unity2018.3以降でObservableWWWの代替手段を紹介します。

そもそもUnity2018.3以降でObservableWWW使わなくない?

そもそも論として、Unity2018.3だとUniTaskが使えるため積極的にObservableを利用する必要がありません。
このような単発の非同期処理であればasync/awaitで十分だからです。

結論: UniTaskを使おう

ということで、結論としては「UniTaskを使う」となります。

GitHubからUniTaskを導入

UniTaskはAssetStoreでは公開されていないため、GitHubから導入する必要があります。

上記の場所から最新のUniTaskのunitypackageをダウンロードして、Unityプロジェクトに導入してください。
UniTaskというプロジェクト名ですけど、歴史的経緯でパッケージ名は「UniRx.Async」になっています。

UniTaskを使ったコードを書く

using UniRx.Async;をした上で。WWWの代わりにUnityWebRequestasync/awaitで待受けるようにしてください。

using System;
using UnityEngine;
using UniRx.Async;
using UnityEngine.Networking;

public class UnityWebRequestSample : MonoBehaviour
{
    async void Start()
    {
        var uri = "https://unity.com/";
        try
        {
            var result = await GetTextAsync(uri);
            Debug.Log(result);
        }
        catch (Exception e)
        {
            Debug.LogException(e);
        }
    }


    /// <summary>
    /// UnityWebRequestをasync/awaitで待ち受ける
    /// </summary>
    private async UniTask<string> GetTextAsync(string uri)
    {
        var uwr = UnityWebRequest.Get(uri);

        // SendWebRequestが終わるまでawait 
        await uwr.SendWebRequest();

        if (uwr.isHttpError || uwr.isNetworkError)
        {
            // 失敗していたらそのまま例外をthrow
            throw new Exception(uwr.error);
        }

        return uwr.downloadHandler.text;
    }
}

これでOKです。

でもやっぱObservableがいい

諸々の諸事情により、UniTask<T>ではなくIObservable<T>に変換したい場合があります。
その場合はToObservable()を用いて変換するとよいでしょう。

Hotのままでいいなら

GetTextureObservable()を実行した時点でGetTextAsync()が実行開始してもよいならこの方法でOKです。

/// <summary>
/// UnityWebRequestを内部で利用したObservable
/// </summary>
/// <param name="uri"></param>
/// <returns></returns>
private IObservable<string> GetTextureObservable(string uri)
{
    return GetTextAsync(uri).ToObservable();
}

/// <summary>
/// UnityWebRequestをasync/awaitで待ち受ける
/// </summary>
private async UniTask<string> GetTextAsync(string uri)
{
    var uwr = UnityWebRequest.Get(uri);

    // SendWebRequestが終わるまでawait 
    await uwr.SendWebRequest();

    if (uwr.isHttpError || uwr.isNetworkError)
    {
        // 失敗していたらそのまま例外をthrow
        throw new Exception(uwr.error);
    }

    return uwr.downloadHandler.text;
}

Coldにしたいなら

GetTextureObservable()Subscribe()したタイミングで、GetTextAsync()が実行開始して欲しいならこの方法で。
Observable.Defer()を使ってください。

/// <summary>
/// UnityWebRequestを内部で利用したObservable
/// </summary>
/// <param name="uri"></param>
/// <returns></returns>
private IObservable<string> GetTextureObservable(string uri)
{
    return Observable.Defer(() => GetTextAsync(uri).ToObservable());
}

/// <summary>
/// UnityWebRequestをasync/awaitで待ち受ける
/// </summary>
private async UniTask<string> GetTextAsync(string uri)
{
    var uwr = UnityWebRequest.Get(uri);

    // SendWebRequestが終わるまでawait 
    await uwr.SendWebRequest();

    if (uwr.isHttpError || uwr.isNetworkError)
    {
        // 失敗していたらそのまま例外をthrow
        throw new Exception(uwr.error);
    }

    return uwr.downloadHandler.text;
}

まとめ

  • UnityWebRequestを使うならUniTaskとasync/awaitで
  • ObservableにしたいならUniTaskから変換する

なお、このままではCancellationTokenを引数にしていた場合ToObservableができない。
なのでこちらを記事をどうぞ。

13
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
7