ハツェの真時代傾向璋

興味を持ったことを書いていく鱗片的な場所から先の未来の場

ダウンロードした画像をuGUIで表示してみよう

こんばんは。ハツェです。
約一年ぶりですね。最近は面白いUdonのアップデートが無くて退屈していました。
今回は、URLの画像をVRChat上に表示してみようという記事です。
動作環境は、Unity : 2019.4.31f1、VCC : 1.0.6SDK - Worlds : 3.1.11、U# : 1.1.7です。

目次


今回の概要

Web上にある画像をVRChatに落として表示する方法について解説します。
いわゆるVideoPlayerの画像バージョンと言ったところですね。
あくまでもU#での実装方法について話しますので、UdonGraphでの実装は公式ドキュメントをご参照ください。

前提知識

サンプルを紹介する前に、幾つか必要となる知識についてご紹介します。

VRCImageDownloader

画像をWebからダウンロードしてくれるクラスです。
VRCImageDownloader.DownloadImage()を呼ぶことで、Webからダウンロードを実行してくれます。
ただし、このクラスはIDisposableを実装しているため、使い終わったらしっかりと破棄する必要があります。
また、この関数には5秒に一回のみという秒数制限が付いており、これより多くの回数ダウンロードしようとすると、意図しない挙動になることがあります。

ダウンロードした画像をマテリアルに反映する方法

VRCImageDownloader.DownloadImage()関数は、四つの引数が指定出来ます。

url: ダウンロードする画像のURLを指定します。
material: ダウンロードした画像を割り当てるマテリアルを指定します。
udonBehaviour: ダウンロード後にイベントを実行するUdonBehaviourを指定します。
textureInfo: ダウンロードする画像の詳細設定を記述したものを指定します。テクスチャの割り当て先もここで指定します。(_MainTextみたいな)

urlを指定しないと、ダウンロードが開始されません。
materialを指定すると、ダウンロード後にtextureInfo.MaterialPropertyで指定したシェーダー変数へ自動的にダウンロードテクスチャを割り当てます。nullでも問題はありません。
udonBehaviourがnullの場合、ダウンロード後に一切イベント関数が呼ばれなくなります。ただし、これがnullの場合、内部的にエラーが出るため、基本的には自身のudonを参照しておくのが良いです。

また、DownloadImage()関数はIVRCImageDownloadを返します。いわゆるTaskみたいなものです。
これにダウンロード状況や、ダウンロードしたテクスチャ等が格納されます。詳しくはこちら

ダウンロード時に実行されるイベント関数

UdonBehaviourには、OnImageLoadSuccess(result)OnImageLoadError(result)の二つのイベント関数が追加されています。
OnImageLoadSuccessはダウンロード成功時、OnImageLoadErrorはダウンロード失敗時にそれぞれ呼ばれます。
今回はこのイベント関数を使用して、Imageコンポーネントにダウンロードした画像を割り当てます。

実際にサンプルを作成してみる

ここからは、VRChat上でURLを指定してCubeをインタラクトすると、画像をダウンロードし、その後表示するというサンプルを作っていきます。
表示させる対象がRawImageであるため、今回はDownloadImage()の自動反映処理を使わず、ダウンロード後の動作を自作していきます。
また、今回作成するサンプルは全てローカルで動作するものであるため、同期させる場合はURLを同期しておくと良いと思います。

完成図

画像を表示するImageとURLを指定するVRCInputField、及びダウンロードを実行させるインタラクトCubeで構成します。

サンプルコード

部分解説

ダウンロードする部分

実際にダウンロードを実行している部分は、以下の部分です。

// ダウンロード実行
_task = _imageDownloader.DownloadImage(_urlInputfield.GetUrl(), null, targetUdon, info);

URLの指定はVRCUrlを渡せば良いので、VRCInputFieldからURLを取得して渡しています。
これで、VRChat上からURLを指定出来るようになります。
反対に、URLを固定したい場合はVRCUrlを宣言すれば良いでしょう。

テクスチャの割り当て

該当部分は以下の通りです。(見やすいように記述を変更しています)

// ダウンロード成功時
public override void OnImageLoadSuccess(IVRCImageDownload result)
{
...
    // テクスチャ反映
    _target.texture = result.Result;
...
}

ダウンロードしたテクスチャの割り当ては、OnImageLoadSuccessイベントで行っています。
OnImageLoadSuccessイベントは、VRCImageDownloader.DownloadImage()の第三引数に自身のudonを設定しておかないと呼ばれないため、注意が必要です。
サンプルコードでは、ついでにサイズをダウンロードした画像の解像度に合わせています。

ロード状況の可視化

該当部分は以下の通りです。(見やすいように記述を変更しています)

private void Update()
{
...
    // ロードバーを動かす
    _loadingBar.value = _task.Progress;
...
}

ダウンロード開始するタイミングで、IVRCImageDownloadを受け取っておくことでダウンロード進行状況を取得出来ます。
でも、現時点だと0と1でしか取得出来てないです...。バグなのかダウンロード速度が高速なのかは不明です...。

実行

あとがき

今回は指定したURLから、画像をダウンロードする方法について紹介しました。
画像と同じ方法で文字列も取得できるようになっています。こちら
文字列が外部から取得できるようになったので、天気予報とかをログイン時に表示出来たりしそうで面白いですね。
色々面白い使い方を模索して頂ければと思います。