Unity ブラウザと相互連携を実装する

ゲーム制作

Unity でブラウザゲームが作れる事を知ったので、簡単ながら試してみました。

しかも、Unity 2018.2 から WebAssembly(wasm) で出力されるようになったので、今までより格段に早く動作するみたいです。

今回の目標

Unity から ブラウザを操作

Unity から ブラウザを操作

ブラウザから Unity を操作

ブラウザから Unity を操作

環境

  • Windows 10 Home 20H2
  • Unity 2020.2.0f1

WebGL ビルド を有効にする

まず初めに、Unity でブラウザゲーム を作るために WebGL ビルド を有効にします。

メニューの ファイル > ビルド設定 の順で選択し、

ファイル > ビルド設定

プラットフォームを WebGL にして「Unity Hub でインストール」を選択します。

Unity Hub でインストール を選択

既に、WebGL をインストールしており ビルド設定が出来る状態なら、この作業を飛ばしても大丈夫です。

WebGL をインストール

Unity Hub が起動したら「WebGL Build Support」にチェックを入れて、実行を押します。

WebGL Build Support にチェック

WebGL がインストールされます。

HTML5 のアイコンが表示されればOK。

HTML5 のアイコンが表示される

Unity を再起動したら WebGLビルド が出来るようになります。

WebGLビルド

相互連携を実装する

では早速、相互連携を実装して行きたいと思います。

Unity側

背景色を単色に変更

Unity の背景を単色に変更します。

そのままでもいいのですが、あまり好きじゃないので単色に変更しました。

左側の「Main Camera」を選択してから、右側の クリアフラグ を「ソリッドカラー」に変更します。

で、その下の 背景項目 を変えれば、ゲーム中の背景色を変えることが出来ます。

クリアフラグ を「ソリッドカラー」に変更

InputField

Unity で文字入力をしたい場合は InputField を使います。

左側の「Canvas」を選択してから、右クリックをして UI > 入力フィールド の順で選択します。

UI > 入力フィールド の順で選択

今回は InputField に処理を追加しないので、そのまま置いておきます。

InputField

Button

イベントを発火させるための 定番 Button を設置します。

InputField と同じ感じで、左側の「Canvas」を選択してから、右クリックをして UI > X ボタン の順で選択します。

UI > X ボタン の順で選択

こんな感じになればOK。

Button

実行してみるとこんな感じ。

Unity 実行確認

スクリプトファイルを作成する

次に、今作ったボタンにイベントを設定して行きます。

Assetsフォルダ内に「Scripts」フォルダを作って、

Scriptsフォルダ作成

Scriptsフォルダ内で右クリックをして、作成 > C# スクリプト の順で選択します。

作成 > C# スクリプト の順で選択

ファイル名は「NewBehaviourScript」のまま変えず。メンドくさいので。

ファイル名は「NewBehaviourScript」のまま

VS Code 等のテキストエディッタで開いて、下記ソースをコピペします。

using UnityEngine;
using UnityEngine.UI;
using System.Runtime.InteropServices;

public class NewBehaviourScript : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern void JavaScriptAlert(string str);

    public InputField inputField;

    public void OnClick()
    {
        Debug.Log(inputField.text);
#if !UNITY_EDITOR && UNITY_WEBGL
        JavaScriptAlert(inputField.text);
#endif
    }

    public void FocusCanvas(string p_focus)
    {
#if !UNITY_EDITOR && UNITY_WEBGL
        if (p_focus == "0")
        {
            WebGLInput.captureAllKeyboardInput = false;
        }
        else
        {
            WebGLInput.captureAllKeyboardInput = true;
        }
#endif
    }

    public void SetInputFieldText(string text)
    {
        inputField.text = text;
    }

}
処理の説明

下記処理は、JavaScript の関数を実行するための宣言になります。 JavaScript に書かれている JavaScriptAlert を呼び出せるようにしています。

[DllImport("__Internal")]
private static extern void JavaScriptAlert(string str);

下記コードで括った処理は、ブラウザで実行した時にしか動作しません。 コレが無いと Unity 上でエラーになるので気をつけましょう。

#if !UNITY_EDITOR && UNITY_WEBGL
    // 処理
#endif

FocusCanvas と SetInputFieldText は JavaScript から呼び出されることを想定して作っています。

ボタンにイベントを設定する

では、今作った処理をボタンに設定して、動くようにします。

左側の Canvas内から「Button」を選択してから、右側の コンポーネントを追加 > スクリプト を選択し、

コンポーネントを追加 > スクリプト を選択

先程作った「New Behaviour Script」を選択します。

New Behaviour Script を選択

こんな感じに、ボタンに New Behaviour Script (スクリプト) コンポーネント が追加されればOK。

New Behaviour Script (スクリプト) コンポーネント

次に、今のスクリプトに InputField を関連付けさせます。

New Behaviour Script (スクリプト) コンポーネント の 入力フィールド にある マルをクリックし、

New Behaviour Script (スクリプト) コンポーネント の 入力フィールド にある マルをクリック

Select InputField ダイアログが表示されるので、「シーン」タブを選択し InputField を選びます。

「シーン」タブを選択し InputField を選択

New Behaviour Script (スクリプト) コンポーネント の 入力フィールド が「なし (入力フィールド)」から「InputField (Input Field)」に変わればOK。

ボタンクリック時のイベント設定

最後に、ボタンをクリックしたらどの関数を発火させるかを設定します。

ボタンのクリック時の +(プラス) を押して、リストを追加します。

+(プラス) を押して、リストを追加

こんな感じに 設定箇所が 1つ 追加されます。

追加確認

先程と同様で マルをクリックし、Select Object から「シーン」タブを選んで、Button を選択します。

「シーン」タブを選んで、Button を選択

「なし (オブジェクト)」から「Button」になればOK。

「なし (オブジェクト)」から「Button」

「No Function」をクリックし NewBehaviourScript > OnClick の順で選択して行きます。

NewBehaviourScript > OnClick の順で選択

こんな感じになれば、イベントの設定は完了です!

イベント設定完了

ブラウザ側

次に、ブラウザ側で動作するスクリプトを作って行きます。

Assetsフォルダに「Plugins」フォルダを作り、

Pluginsフォルダを作成

Windows のエクスプローラで開きます。

Windows のエクスプローラで開く

何も無いところで右クリックをして 新規作成 >テキスト ドキュメント を選択し、空のテキストファイルを作成します。

新規作成 >テキスト ドキュメント を選択

ファイル名は「JavaScriptLibrary.jslib」にします。

ファイル名は「JavaScriptLibrary.jslib」

拡張子も「jslib」に変更するので、ダイアログが出ますが「はい」を選択します。

拡張子変更確認ダイアログ

拡張子が非表示の場合は、表示タブの「ファイル名拡張子」にチェックを入れると、表示されるようになります。

表示タブの「ファイル名拡張子」にチェックを入れる

今作った「JavaScriptLibrary.jslib」をテキストエディタで開いて、下記コードをコピペします。

mergeInto(LibraryManager.library, {
  JavaScriptAlert: function (str) {
    window.alert(Pointer_stringify(str));
  },
});

ビルド

ここまで来たら、もう少しで完成です! 頑張って!!!

WebGL を使って ブラウザ向けにビルドします。

メニューから ファイル > ビルド設定 を開き、

ファイル > ビルド設定

プラットフォームを「WebGL」に変更し、開発ビルドにチェックを入れてから ビルドボタンを押します。

プラットフォームを「WebGL」に変更しビルド

ビルド先フォルダを聞かれるので、新規で「web」フォルダを作り、その中にビルドしてもらいます。

「web」フォルダを作る

ビルドが正常に完了すると、下記ファイルが出力されます。

  • Build
  • TemplateData
  • index.html
ビルド正常終了

最後に「index.html」ファイルを修正して完成です。

<!DOCTYPE html>
<html lang="en-us">
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Unity WebGL Player | New Unity Project</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body style="text-align: center" class="m-3">
  <div class="container">
    <div class="row">
      <div class="col-auto">
        <canvas class="border border-success" id="unity-canvas" style="width: 270px; height: 480px; background: #FFFFFF"></canvas>
      </div>
      <div class="col-auto">
        <div class="border border-success p-3">
            <div class="form-group">
              <input type="text" class="form-control form-control-sm" id="exampleInput1">
            </div>
            <button type="button" class="btn btn-outline-success btn-sm" onclick="unitySendMessage()">Unityに送信</button>
        </div>
      </div>
    </div>
  </div>
  <script src="Build/web.loader.js"></script>
  <script>
    var unityInstance = null;
    createUnityInstance(document.querySelector("#unity-canvas"), {
      dataUrl: "Build/web.data",
      frameworkUrl: "Build/web.framework.js",
      codeUrl: "Build/web.wasm",
      streamingAssetsUrl: "StreamingAssets",
      companyName: "DefaultCompany",
      productName: "New Unity Project",
      productVersion: "0.1",
    }).then(x => unityInstance = x);
  </script>
  <script> 
    document.addEventListener('click', function(e) { 
     if (e.target.id == "unity-canvas") { 
      // Clicked on canvas 
      unityInstance.SendMessage("Button", "FocusCanvas", "1");
     } else { 
      // Clicked outside of canvas 
      unityInstance.SendMessage("Button", "FocusCanvas", "0");
     } 
    }); 
    function unitySendMessage(params) {
      unityInstance.SendMessage("Button", "SetInputFieldText", $("#exampleInput1").val());
    }
</script> 
</body>
</html>

実行

しかし「index.html」をダブルクリックしても、実行する事が出来ません。

GitHub にホスティングしないと駄目なのですが、それは次回説明します。

今回は「ビルドして実行」から動作確認をします。

注意事項として、ビルドをすると「index.html」が元に戻ってしまうので、再度コピペが必要です。

おわりに

デモサイト

Unity WebGL Player | New Unity Project

ソースコード

GitHub

参考

WebGL: ブラウザースクリプトとの相互作用 - Unity マニュアル
Web 用のコンテンツを構築するときは、Web ページ上の他の要素とやり取りする必要があります。また、Web API を使用して Unity が現在デフォルトで公開していない機能を実装したい場合もあるかもしれません。 いずれの場合も、ブラウザーの JavaScript エンジンと直接やり取りする必要があります。Unit...
html5 - ユニティWebGL - 予防すべてのマウス/キーボード入力を食べるから?
Unity 5.4すべての3DコンテンツをUnityサイドで処理するUnity WebGLアプリケーション(ゲームではない)を構築し、すべてのUIをHTML/CSS/JSを使用して構築します。デフォルトでは、WebGLInput.captureAllKeyboardInputは、任意のキーボードコントロールが自動的にで...
タイトルとURLをコピーしました