Unity(WebGL)のC#とブラウザのJavaScriptの連携
Unity(WebGL)のC#とブラウザのJavaScriptの連携方法をまとめました。
1. Unity(WebGL)のC#とブラウザのJavaScriptの連携
Unity(WebGL)のC#とブラウザのJavaScript連携させることで、次のようなことを実現できます。
・Unity(WebGL)からHTMLテンプレート上の他の要素を操作。
・Unity(WebGL)からブラウザが提供するWeb APIを利用。
・Webアプリの部品としてUnity(WebGL)を利用。
2. Unity(WebGL)のC#からブラウザのJavaScriptを呼び出す
Unityプロジェクトに「JavaScriptプラグイン」を追加し、Unity(WebGL)のC#から「JavaScriptプラグイン」の関数を呼び出します。「JavaScriptプラグイン」から、Webブラウザの標準API(alert(), console.log())、およびHTMLテンプレートで定義されてるWeb APIを呼び出すことができます。
Unity(WebGL)のC#からJavaScriptを呼び出す手順は、次のとおり。
(1) Assetsフォルダ直下にPluginsフォルダを作成し、JavaScriptプラグイン(sample.jslib)を追加。
・Assets/Plugins/sample.jslib
mergeInto(LibraryManager.library, {
// 関数呼び出し
Hello: function () {
window.alert("Hello, world!");
},
// 数値型の引数と戻り値
AddNumbers: function (x, y) {
return x + y;
},
// 数値型以外の型の引数
PrintFloatArray: function (array, size) {
for(var i = 0; i < size; i++)
console.log(HEAPF32[(array >> 2) + i]);
},
// 文字列型の引数
HelloString: function (str) {
window.alert(Pointer_stringify(str));
},
// 文字列の戻り値
StringReturnValueFunction: function () {
var returnStr = "bla";
var bufferSize = lengthBytesUTF8(returnStr) + 1;
var buffer = _malloc(bufferSize);
stringToUTF8(returnStr, buffer, bufferSize);
return buffer;
},
// WebGLテクスチャのバインド
BindWebGLTexture: function (texture) {
GLctx.bindTexture(GLctx.TEXTURE_2D, GL.textures[texture]);
},
});
(2) Hierarchyウィンドウに空のゲームオブジェクトを作成し、以下のスクリプトを追加。
Unity(WebGL)のC#からJavaScriptプラグインを呼び出すコードになります。
・Assets/Scripts/JsTest.cs
using UnityEngine;
using System.Runtime.InteropServices;
public class JsTest : MonoBehaviour
{
[DllImport("__Internal")]
private static extern void Hello();
[DllImport("__Internal")]
private static extern void HelloString(string str);
[DllImport("__Internal")]
private static extern void PrintFloatArray(float[] array, int size);
[DllImport("__Internal")]
private static extern int AddNumbers(int x, int y);
[DllImport("__Internal")]
private static extern string StringReturnValueFunction();
[DllImport("__Internal")]
private static extern void BindWebGLTexture(int texture);
// スタート時に呼ばれる
void Start()
{
// 関数呼び出し
Hello();
// 数値型の引数と戻り値
int result = AddNumbers(5, 7);
Debug.Log(result);
// 数値型以外の型の引数
float[] myArray = new float[10];
PrintFloatArray(myArray, myArray.Length);
// 文字列型の引数
HelloString("This is a string.");
// 文字列の戻り値
Debug.Log(StringReturnValueFunction());
// WebGLテクスチャのバインド
var texture = new Texture2D(0, 0, TextureFormat.ARGB32, false);
BindWebGLTexture(texture.GetNativeTextureID());
}
}
(3) ビルドして実行。
アラートやJavaScriptコンソールのログとして結果が出力されます。
3. JavaScriptプラグインの詳細
「JavaScriptプラグイン」の詳細は、次のとおり。
◎ JavaScriptプラグインの関数のインポート
UnityのC#からJavaScriptプラグインの関数を利用するには、「DllImport」と「extern」で関数のインポートを宣言する必要があります。
[DllImport("__Internal")]
private static extern void 関数名();
◎ 数値型の引数と戻り値
数値型の引数と戻り値は、変換なし利用できます。
int result = AddNumbers(5, 7); ... Unity(WebGL)のC#
↓
AddNumbers: function (x, y) { ... JavaScriptプラグイン
return x + y;
},
◎ 数値型以外の型の引数
数値型以外の型(数値型配列など)の引数は、emscriptenヒープのポインタとして渡します。
float[] myArray = new float[10]; ... Unity(WebGL)のC#
PrintFloatArray(myArray, myArray.Length);
↓
PrintFloatArray: function (array, size) { ... JavaScriptプラグイン
for(var i = 0; i < size; i++)
console.log(HEAPF32[(array >> 2) + i]);
},
emscriptenはオープンソースのトランスコンパイラで、これを利用することで、C言語やC++で書かれたプログラムをasm.jsに変換しています。emscriptenヒープにアクセスするには、以下の型付き配列バッファを利用します。
・HEAP8: 8ビットの符号付きメモリ
・HEAP16: 16ビットの符号付きメモリ
・HEAP32: 32ビットの符号付きメモリ
・HEAPU8: 8ビットの符号なしメモリ
・HEAPU16: 16ビットの符号なしメモリ
・HEAPU32: 32ビットの符号なしメモリ
・HEAPF32: 32ビットの浮動小数メモリ
・HEAPF64: 64ビットの浮動小数メモリ
◎ 文字列型の引数
文字列型の引数は、Pointer_stringify()を使用して、emscriptenヒープのポインタからJavaScript文字列に変換できます。
HelloString("This is a string."); ... Unity(WebGL)のC#
↓
HelloString: function (str) { ... JavaScriptプラグイン
window.alert(Pointer_stringify(str));
},
◎ 文字列型の戻り値
文字列型の戻り値は、_malloc()でメモリを割り当てた後、stringToUTF8()でJavaScript文字列を書き込む必要があります。このメモリの解放はil2cppランタイムが行います。
Debug.Log(StringReturnValueFunction()); ... Unity(WebGL)のC#
↓
StringReturnValueFunction: function () { ... JavaScriptプラグイン
var returnStr = "bla";
var bufferSize = lengthBytesUTF8(returnStr) + 1;
var buffer = _malloc(bufferSize);
stringToUTF8(returnStr, buffer, bufferSize);
return buffer;
},
◎ WebGLテクスチャのバインド
WebGLテクスチャにアクセスするために、emscriptenはGL.textures配列を提供します。これによって、UnityからWebGLテクスチャをバインドして、テクスチャIDを取得することができます。
var texture = new Texture2D(0, 0, TextureFormat.ARGB32, false); ... Unity(WebGL)のC#
BindWebGLTexture(texture.GetNativeTextureID());
↓
BindWebGLTexture: function (texture) { ... JavaScriptプラグイン
GLctx.bindTexture(GLctx.TEXTURE_2D, GL.textures[texture]);
},
JavaScript関数との相互作用について詳しくは、emscriptenのドキュメントを参照してください。
4. ブラウザスのJavaScriptからUnity(WebGL)のC#を呼び出す
ブラウザのJavaScript、またはJavaScriptプラグインから、gameInstance.SendMessage()を呼ぶことで、Unity(WebGL)内のゲームオブジェクトのメソッドを呼ぶことができます。
ブラウザのJavaScriptからUnity(WebGL)のC#を呼び出す手順は、次のとおり。
(1) HTMLテンプレート「index.html」に、gameInstance.SendMessage()を呼ぶコードを追加。
ボタン押下時に呼んでいます。
<script>
function onClick() {
gameInstance.SendMessage('JsTest', 'SetText', 'This is a text.');
}
</script>
<input type="button" value="OK" onClick="onClick()" />
gameInstance.SendMessage()の引数の意味は、次のとおり。
SendMessage(objectName, methodName, value...);
・objectName: シーン内のオブジェクト名。
・methodName: オブジェクトにアタッチされているメソッド名。
・value: 引数(文字列、数字など)。
(2) UnityのシーンにUIコンポーネント「Text」を追加。
ブラウザのJavaScriptから渡された文字列を表示します。
(3) ゲームオブジェクト「JsTest」のスクリプト「JsTest」に以下のコードを追加。
public Text label;
public void SetText(string text)
{
label.text = text;
}
(4) UIコンポーネント「Text」をコンポーネント「JsTest」のlabelにドラッグ&ドロップ。
(5) ビルドして実行。
OKボタンを押すと、ラベルの文字列が変わります。
この記事が気に入ったらサポートをしてみませんか?