Re: note

技術的な知見やポエムなど役に立たない情報を書き連ねる場所

UniWebView 3を使う

f:id:hik0leaf:20190906233703p:plain

Unity上でWebブラウザの機能を使えるようにするためのWebViewアセットはいくつかありますが、ここではその一つであるUniWebView 3の解説を行います。

1. UniWebView 3とは

Unity上でWebブラウザを表示することができるアセットで、インターネットWebブラウジングだけでなく、ローカルHTMLの読み込みやCSSスタイリング、Javascriptの実行が可能です。

$25の有料アセット(2019.09時点)なだけあって ドキュメント がしっかり整備されています。使用する際はドキュメントを参照すると良いでしょう。

対応プラットフォームはiOS 9.0以上、Android 5.0以上に対応しており、macOSのUnity Editor上でも動作します。ただmacOSのUnity Editorで動かすときは、Scene ViewやGame View内ではなく独立のウィンドウで表示されるためデバッグ用途としてはやや使いづらい部分があります。

また、Windowsには対応していないことからもモバイルプラットフォーム向けのアセットといえます。

2. 導入

Asset StoreからUniWebView 3を購入してインポートします。

assetstore.unity.com

3. ひとまず使ってみる

インポートできたらProjectの UniWebView > Demo > UniWebViewDemo シーンを開きます。実行すると以下のようにウィンドウが開いてUniWebViewのドキュメントサイトが表示されます。

f:id:hik0leaf:20190907111905p:plain
デモシーンの場所

f:id:hik0leaf:20190907111947p:plain
デモシーンの実行結果

接続先を変更したい場合はヒエラルキーにあるUniWebView PrefabにアタッチされているUniWebView Scriptの Url On Start の欄に任意のURLを入力します。

f:id:hik0leaf:20190907112212p:plain
接続先の変更

4. 色々使ってみる

ドキュメントには チュートリアル がありますので、これに沿って進めていくと大体いい感じに使えるようになります。ここでは要点だけに絞って解説します。

まずは任意のシーンに空のGameObjectを作成して WebView と名前を付けます。次にProjectに WebView というスクリプトを作成して、先ほど作成したWebViewオブジェクトにアタッチします。

f:id:hik0leaf:20190907114729p:plain
WebViewオブジェクトの作成とスクリプトのアタッチ

スクリプトに以下のコードを貼り付けます。

using UnityEngine;

public class WebView : MonoBehaviour
{
    UniWebView webView;

    void Start () {
        var webViewGameObject = new GameObject("UniWebView");
        webView = webViewGameObject.AddComponent<UniWebView>();

        webView.Frame = new Rect(0, 0, Screen.width, Screen.height);
    
        webView.Load("https://www.google.co.jp/");
        webView.Show();
    }
}

実行すると以下のようになります。

f:id:hik0leaf:20190907131827p:plain
実行結果

5. ローカルHTMLファイルの読み込み

次にネット上のサイトではなく、ローカルにあるHTMLファイルを読み込んで表示させてみます。

まず StreamingAssets フォルダを作成します。

f:id:hik0leaf:20190907132308p:plain
StreamingAssetsフォルダの作成

以下のHTMLファイルを作成し、sample.html と名前を付けてStreamingAssets フォルダに保存します。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        Hello World
    </body>
</html>

先ほど作成したスクリプト WebView.cs を以下のように変更します。

void Start () {
    var webViewGameObject = new GameObject("UniWebView");
    webView = webViewGameObject.AddComponent<UniWebView>();

    webView.Frame = new Rect(0, 0, Screen.width, Screen.height);

    var url = UniWebViewHelper.StreamingAssetURLForPath("sample.html");
    webView.Load(url);
    webView.Show();
}

実行すると以下のように表示されます。StreamingAssets フォルダ内にjavascriptファイルやcssファイルを配置すればHTMLから参照することが可能です。

f:id:hik0leaf:20190907134028p:plain
ローカルHTMLファイルの表示結果

6. Unity(C#) → WebView(Javascript)の通信

UniWebViewではUnity側からJavascriptの関数を実行することが可能です。

sample.html を以下のように変更します。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        Hello World
    </body>

    <script language="javascript" type="text/javascript">
        function SumTest(a, b) {
            return a + b;
        }
    </script>
</html>

WebView.cs を以下のように変更します。

using UnityEngine;

public class WebView : MonoBehaviour
{
    UniWebView webView;

    void Start () {
        var webViewGameObject = new GameObject("UniWebView");
        webView = webViewGameObject.AddComponent<UniWebView>();

        webView.Frame = new Rect(0, 0, Screen.width, Screen.height);
    
        var url = UniWebViewHelper.StreamingAssetURLForPath("sample.html");
        webView.Load(url);
        webView.Show();
    }

    void Update() {
        if (Input.GetKeyDown(KeyCode.Space)) {
            webView.EvaluateJavaScript("SumTest(1, 2)", (payload) => {
                if (payload.resultCode.Equals("0")) {
                    Debug.Log("1 + 2 = " + payload.data);
                }
            });
        }
    }
}

実行してスペースキーを押すと以下のようになります。

f:id:hik0leaf:20190907140352p:plain
実行結果

Unity→Javascript関数の実行は以下の部分で行っています。EvaluateJavaScript の第一引数でHTMLファイル側に記述したJavascriptの関数名を指定します。今回の例では引数も一緒に渡しています。

さらにJavascript関数の戻り値も第二引数で受け取ることが可能になっています。例ではラムダ式を用いてpayload変数で値を受け取っています。戻り値には resultCode が付与されており、0 で正常終了。0 以外はエラーと判断することができるようになっています。

webView.EvaluateJavaScript("SumTest(1, 2)", (payload) => {
    if (payload.resultCode.Equals("0")) {
        Debug.Log("1 + 2 = " + payload.data);
    }
});

うまくいかない場合は resultCode を調べてみると良いでしょう。Javascriptの関数名が間違っていたりするとエラーになります。戻り値のデータは data で取得することができます。

7. WebView(Javascript) → Unity(C#)の通信

Javascript側からUnity側の関数を呼び出すことも可能です。

sample.html を以下のように変更します。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <input type="text" id="mytext">
        <input type="button" id="btn" value="OK" onclick="OnButtonClick();">
    </body>

    <script language="javascript" type="text/javascript">
        function OnButtonClick() {
            var message = document.getElementById('mytext').value;
            window.location.href = "uniwebview://action?value1=" + message + "&value2=" + "hoge";
        }

        function SumTest(a, b) {
            return a + b;
        }
    </script>
</html>

WebView.cs を以下のように変更します。

using UnityEngine;

public class WebView : MonoBehaviour
{
    UniWebView webView;

    void Start () {
        var webViewGameObject = new GameObject("UniWebView");
        webView = webViewGameObject.AddComponent<UniWebView>();

        webView.Frame = new Rect(0, 0, Screen.width, Screen.height);
    
        var url = UniWebViewHelper.StreamingAssetURLForPath("sample.html");
        webView.Load(url);
        webView.Show();

        webView.OnMessageReceived += (view, message) => {
            if (message.Path.Equals("action")) {
                Debug.Log("value1: " + message.Args["value1"]);
                Debug.Log("value2: " + message.Args["value2"]);
            }
        };
    }

    void Update() {
        if (Input.GetKeyDown(KeyCode.Space)) {
            webView.EvaluateJavaScript("SumTest(1, 2)", (payload) => {
                if (payload.resultCode.Equals("0")) {
                    Debug.Log("1 + 2 = " + payload.data);
                }
            });
        }
    }
}

実行するとWebView上でText入力とボタンが表示されるので、Textに適当な値を入れて[OK]ボタンを押します。

f:id:hik0leaf:20190907143607p:plain
Javascript→Unityへの送信

うまく動作すると以下ようにDebug.Logに表示されます。

f:id:hik0leaf:20190907143932p:plain
実行結果

JavascriptからUnityへは

window.location.href = "uniwebview://action?value1=" + message + "&value2=" + "hoge";

で値を送ることができます。& でパラメータをつなげることで複数の値を送ることができます。

Unity側は

webView.OnMessageReceived += (view, message) => {
    if (message.Path.Equals("action")) {
        Debug.Log("value1: " + message.Args["value1"]);
        Debug.Log("value2: " + message.Args["value2"]);
    }
};

で値を受け取っています。メッセージのPathはactionとしていますが送り手と受け手で一致していれば任意の値で構いません。値は message.Args[""] でキーを指定することで取得することができます。

8. まとめ

UniWebView 3を使うとUnity上でWebブラウザの機能が使えることがわかりました。Unity上からJavascriptを使ってWebの豊富な資源を活用したり、洗練されたUIなどを流用することができるようになるため、手段の1つとして覚えておくと便利でしょう。