WebGL:與瀏覽器腳本交互
構建適用於 Web 的內容時,可能需要與網頁上的其他元素進行通信。或者,您可能希望使用 Unity 當前在默認情況下未公開的 Web API 來實現功能。在這兩種情況下,都需要直接與瀏覽器的 JavaScript 引擎連接。Unity WebGL 提供了不同的方法來執行此操作。
從 Unity 腳本調用 JavaScript 函數
在項目中使用瀏覽器 JavaScript 的建議方法是將 JavaScript 源代碼添加到項目中,然后直接從腳本代碼中調用這些函數。為此,請使用 .jslib 擴展名將包含 JavaScript 代碼的文件放置在 Assets 文件夾中的“Plugins”子文件夾下。插件文件需要有如下所示的語法:
mergeInto(LibraryManager.library, {
Hello: function () {
window.alert("Hello, world!");
},
HelloString: function (str) {
window.alert(Pointer_stringify(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]);
},
});
然后,可從 C# 腳本調用這些函數,如下所示:
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(0, 0, TextureFormat.ARGB32, false);
BindWebGLTexture(texture.GetNativeTextureID());
}
}
簡單的數字類型可在函數參數中傳遞給 JavaScript,無需進行任何轉換。其他數據類型將作為 emscripten 堆(實際上就是 JavaScript 中的一個大型數組)中的指針進行傳遞。對於字符串,可使用 Pointer_stringify
helper 函數轉換為 JavaScript 字符串。要返回字符串值,必須調用 _malloc 來分配一些內存,並調用 stringToUTF8 helper 函數向其中寫入 JavaScript 字符串。如果字符串是返回值,則 il2cpp 運行時將負責為您釋放內存。對於原始類型的數組, emscripten
針對內存的不同大小的整數、無符號整數或浮點數表示形式,提供其堆的不同 ArrayBufferViews:HEAP8、HEAPU8、HEAP16、HEAPU16、HEAP32、HEAPU32、HEAPF32、HEAPF64。為了在 WebGL 中訪問紋理, emscripten
提供了 GL.textures
數組,該數組將本機紋理 ID 從 Unity 映射到 WebGL 紋理對象。可在 emscripten 的 WebGL 上下文 GLctx
中調用 WebGL 函數。
有關如何與 JavaScript 交互的更多信息,請參閱 emscripten 文檔。
另外,請注意,在 Unity 安裝文件夾中有幾個插件可供參考(位於 PlaybackEngines/WebGLSupport/BuildTools/lib 和 PlaybackEngines/WebGLSupport/BuildTools/Emscripten/src/library*
中)。
從 JavaScript 調用 Unity 腳本函數
有時需要從瀏覽器的 JavaScript 向 Unity 腳本發送一些數據或通知。建議的做法是調用內容中的游戲對象上的方法。如果要從嵌入在項目中的 JavaScript 插件執行調用,可使用以下代碼:
unityInstance.SendMessage(objectName, methodName, value);
其中,objectName 是場景中的對象名稱;methodName 是當前附加到該對象的腳本中的方法名稱;value 可以是字符串、數字,也可為空。例如:
unityInstance.SendMessage('MyGameObject', 'MyFunction');
unityInstance.SendMessage('MyGameObject', 'MyFunction', 5);
unityInstance.SendMessage('MyGameObject', 'MyFunction', 'MyString');
如果希望從嵌入頁面的全局作用域內執行調用,請參閱下面的代碼可見性部分。
從 Unity 腳本調用 C 函數
由於 Unity 使用 emscripten 將源代碼從 C/C++ 代碼編譯為 JavaScript,因此您也可以使用 C/C++ 代碼編寫插件,並從 C# 調用這些函數。因此,您可以不使用上面示例中的 jslib 文件,而是在項目中使用 C/C++ 文件;它將自動使用您的腳本實現編譯,並且您可以從中調用函數,就像上面的 JavaScript 示例一樣。
如果使用 C++ (.cpp) 來實現該插件,則必須確保使用 C 鏈接來聲明函數以免發生名稱錯用問題:
# include <stdio.h>
extern "C" void Hello ()
{
printf("Hello, world!\n");
}
extern "C" int AddNumbers (int x, int y)
{
return x + y;
}
更多閱讀請參考
官網
UNITY | WebGL C# 調用 JavaScript函數
UNITY | WebGL JavaScript 調用 C#函數