Unity WebGL 腳本互交


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#函數
我的老婆


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM