When building content for the web, you might need to communicate with other elements on your web page. Or you might want to implement functionality using Web APIs which Unity doesn’t expose by default. In both cases, you need to directly interface with the browser’s JavaScript engine. Unity WebGL provides different methods to do this.
The recommended way of using browser JavaScript in your project is to add your JavaScript sources to your project, and then call those functions directly from your script code. To do so, place files with JavaScript code using the .jslib
extension in the Assets folder > Plugins subfolder. The plugin file needs to have a syntax like this:
mergeInto(LibraryManager.library, {
Hello: function () {
window.alert("Hello, world!");
},
HelloString: function (str) {
window.alert(UTF8ToString(str));
},
PrintFloatArray: function (array, size) {
for(var i = 0; i < size; i++)
console.log(HEAPF32[(array >> 2) + i]);
},
AddNumbers: function (x, y) {
return x + y;
},
StringReturnValueFunction: function () {
var returnStr = "bla";
var bufferSize = lengthBytesUTF8(returnStr) + 1;
var buffer = _malloc(bufferSize);
stringToUTF8(returnStr, buffer, bufferSize);
return buffer;
},
BindWebGLTexture: function (texture) {
GLctx.bindTexture(GLctx.TEXTURE_2D, GL.textures[texture]);
},
});
Then, you can call these functions from your C# scripts as follows:
using UnityEngine;
using System.Runtime.InteropServices;
public class NewBehaviourScript : 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();
HelloString("This is a string.");
float[] myArray = new float[10];
PrintFloatArray(myArray, myArray.Length);
int result = AddNumbers(5, 7);
Debug.Log(result);
Debug.Log(StringReturnValueFunction());
var texture = new Texture2D(1, 1, TextureFormat.ARGB32, false);
BindWebGLTexture(texture.GetNativeTexturePtr());
}
}
More Details:
UTF8ToString
ヘルパー関数を使用して JavaScript 文字列に変換できます。_malloc
を呼び出してメモリを割り当て、stringToUTF8
ヘルパー関数を呼び出して、JavaScript 文字列を書き込みます。文字列が戻り値の場合は、IL2CPP ランタイムは自動的にメモリを解放します。emscripten
は、メモリのさまざまなサイズの整数、符号なし整数、浮動小数点数に対して、次のようなさまざまな ArrayBufferView
をヒープに提供します。heap8、heapu8、heap16、heapu16、heap32、heapu32、heapf32、heapf64。GL.textures
配列を提供します。emscripten の WebGL コンテキスト GLctx
で WebGL 関数を呼び出すことができます。JavaScript と相互作用する方法に関して詳しくは、emscripten ドキュメント を参照してください。
In addition, there are several plugins in the Unity installation folder that you can use as reference: PlaybackEngines/WebGLSupport/BuildTools/lib
and PlaybackEngines/WebGLSupport/BuildTools/Emscripten/src/library*
.
すべてのビルドコードを独自のスコープで実行することが推奨されます。これにより、埋め込みページのコードと衝突することなく、任意のページにコンテンツを埋め込むことができ、同じページに複数のビルドを埋め込むことができます。
プロジェクト内の JavaScript コードがすべて .jslib プラグインの形式である場合、この JavaScript コードはコンパイルされたビルドと同じスコープ内で実行され、コードは以前のバージョンの Unity と同じように動作します。例えば、Module、SendMessage、HEAP8、ccall など のオブジェクトと関数は、JavaScript プラグインコードから直接見ることができます。
However, if you are planning to call the internal JavaScript functions from the global scope of the embedding page, you must use the unityInstance
variable in your WebGL Template index.html
. Do this after the Unity engine instantiation succeeds, for example:
var myGameInstance = null;
script.onload = () => {
createUnityInstance(canvas, config, (progress) => {...}).then((unityInstance) => {
myGameInstance = unityInstance;
…
Then, you can send a message to the build using myGameInstance.SendMessage()
, or access the build Module object using myGameInstance.Module
.
The recommended way of sending data or notification to the Unity script from the browser’s JavaScript is to call methods on GameObjects in your content. If you are making the call from a JavaScript plugin, embedded in your project, you can use the following code:
MyGameInstance.SendMessage(objectName, methodName, value);
objectName はシーンのオブジェクトの名。 methodName は、現在オブジェクトにアタッチされているスクリプトのメソッド名です。value には文字列、数字などで、以下の例のように空にしておくことも可能です。
MyGameInstance.SendMessage('MyGameObject', 'MyFunction');
MyGameInstance.SendMessage('MyGameObject', 'MyFunction', 5);
MyGameInstance.SendMessage('MyGameObject', 'MyFunction', 'MyString');
If you would like to make a call from the global scope of the embedding page, see the Code Visibility section.
Unity compiles your sources into JavaScript from C/C++ code using emscripten, so you can also write plugins in C/C++ code, and call these functions from C#. Therefore, instead of the .jslib
file in the example above, you could have a C/C++ file in your project, which is automatically get compiled with your scripts, and you can call functions from it, just like in the JavaScript example above.
If you are using C++ (.cpp) to implement the plugin, then you must ensure the functions are declared with C linkage to avoid name mangling issues:
# include <stdio.h>
extern "C" void Hello ()
{
printf("Hello, world!\n");
}
extern "C" int AddNumbers (int x, int y)
{
return x + y;
}
ノート: Unity は Emscripten バージョン 2.0.19 ツールチェーンを使用しています。
2021.2 以降で Pointer__stringify() を UTF8ToString に置き換えました。
2020.1 で unity.Instance が createUnityInstance に変更されました。
コード例の誤りを修正
2019.1 で WebGL インスタンスの名称が gameInstance から unityInstance に変更されました。
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.