search
LoginSignup
7

More than 3 years have passed since last update.

posted at

updated at

Organization

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

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ができない。
なのでこちらを記事をどうぞ。

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
What you can do with signing up
7