10. WebGL: Interacting with browser scripting

WebGL:與瀏覽器腳本進行交互

在為網(wǎng)絡(luò)構(gòu)建內(nèi)容時,您可能需要與網(wǎng)頁上的其他元素進行通信?;蛘吣赡芟M褂肬nity默認現(xiàn)在不公開的Web API實現(xiàn)功能。在這兩種情況下,您都需要直接與瀏覽器的JavaScript引擎進行交互。 Unity WebGL提供了不同的方法來執(zhí)行此操作。

Calling JavaScript functions from Unity scripts 從Unity腳本調(diào)用JavaScript函數(shù)

在項目中使用瀏覽器JavaScript的推薦方法是將JavaScript源添加到項目中,然后直接從腳本代碼中調(diào)用這些函數(shù)。為此,請在Assets文件夾中的“Plugins”子文件夾下使用.jslib擴展名(如UnityScript編譯器的常規(guī).js文件)將JavaScript代碼放置到文件中。插件文件需要這樣的語法:

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#腳本中調(diào)用這些函數(shù),如下所示:

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());
    }
}

簡單的數(shù)字類型可以通過函數(shù)參數(shù)傳遞給JavaScript,而不需要任何轉(zhuǎn)換。其他數(shù)據(jù)類型將作為emscripten堆中的指針傳遞(這實際上只是JavaScript中的一個大數(shù)組)。對于字符串,您可以使用Pointer_stringify幫助函數(shù)轉(zhuǎn)換為JavaScript字符串。為了返回一個字符串值,你需要調(diào)用_malloc來分配一些內(nèi)存和stringToUTF8輔助函數(shù)來為它寫一個JavaScript字符串。如果字符串是一個返回值,那么il2cpp運行時將負責(zé)為您釋放內(nèi)存。對于基本類型的數(shù)組,emscripten將不同大小的整數(shù),無符號整數(shù)或浮點內(nèi)存表示形式的堆棧提供給它的堆堆:HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64。要訪問WebGL中的紋理,emscripten提供了GL.textures數(shù)組,它將Unity中的原生紋理ID映射到WebGL紋理對象。可以在emscripten的WebGL上下文GLctx上調(diào)用WebGL函數(shù)。

Legacy ways of calling JavaScript code from Unity 從Unity調(diào)用JavaScript代碼的傳統(tǒng)方式

注意:
從Unity 5.6開始,從Unity調(diào)用JavaScript代碼的推薦方式是通過.jslib插件。下面描述的方法僅出于兼容性原因而被支持,并且可能在Unity的未來版本中被棄用。

您可以使用Application.ExternalCall()Application.ExternalEval()函數(shù)來調(diào)用嵌入網(wǎng)頁上的JavaScript代碼。請注意,表達式在構(gòu)建的本地范圍內(nèi)進行評估。如果您想在全局范圍內(nèi)執(zhí)行JavaScript代碼,請參閱下面的代碼Code Visibility(可見性)部分。

Calling Unity scripts functions from JavaScript 從JavaScript調(diào)用Unity腳本函數(shù)

有時您需要從瀏覽器的JavaScript中向Unity腳本發(fā)送一些數(shù)據(jù)或通知。推薦的方法是在你的內(nèi)容中調(diào)用GameObjects上的方法。如果您正在使用嵌入到項目中的JavaScript插件進行調(diào)用,則可以使用以下代碼:

SendMessage(objectName, methodName, value);

其中objectName是場景中對象的名稱; methodName是腳本中當(dāng)前附加到該對象的方法的名稱;值可以是字符串,value,也可以是空的。例如:

SendMessage('MyGameObject', 'MyFunction');
SendMessage('MyGameObject', 'MyFunction', 5);

SendMessage('MyGameObject', 'MyFunction', 'MyString');

如果您想從嵌入頁面的全局范圍撥打電話,請參閱下面的代碼可見性部分。

Calling C++ functions from Unity scripts 從Unity腳本調(diào)用C++函數(shù)

由于Unity使用emscripten將C++源代碼編譯為JavaScript,您還可以使用C或C++代碼編寫插件,并從C#中調(diào)用這些函數(shù)。因此,與上例中的jslib文件不同,您可以在項目中使用如下所示的c文件 - 它將自動使用腳本進行編譯,并且可以從中調(diào)用函數(shù),就像上面的JavaScript示例中一樣。

如果您使用C++(.cpp)實現(xiàn)插件,那么您必須確保使用C鏈接聲明函數(shù)以避免名稱修改問題。

#include <stdio.h>
void Hello ()
{
    printf("Hello, world!\n");
}
int AddNumbers (int x, int y)
{
    return x + y;
}

Code visibility 代碼可見性

從Unity 5.6開始,所有構(gòu)建代碼都在其自己的范圍內(nèi)執(zhí)行。這種方法可以將游戲嵌入到任意頁面中,而不會與嵌入頁面代碼發(fā)生沖突,并且可以在同一頁面上嵌入多個構(gòu)建。

如果您的項目中包含.jslib插件形式的所有JavaScript代碼,那么此JavaScript代碼將與編譯的內(nèi)部版本在相同的范圍內(nèi)運行,并且您的代碼的工作方式應(yīng)與以前版本的Unity中的方式幾乎相同(適用于例如,以下對象和函數(shù)應(yīng)該直接從JavaScript插件代碼中可見:Module,SendMessage,HEAP8,ccall等)。

但是,如果打算從嵌入頁面的全局范圍調(diào)用內(nèi)部JavaScript函數(shù),則應(yīng)始終假定頁面上嵌入了多個構(gòu)建版本,因此應(yīng)明確指定要引用的構(gòu)建版本。例如,如果你的游戲已經(jīng)被實例化為:

var gameInstance = UnityLoader.instantiate("gameContainer", "Build/build.json", {onProgress: UnityProgress});

然后,您可以使用gameInstance.SendMessage()向構(gòu)建發(fā)送消息,或訪問構(gòu)建模塊對象,如gameInstance.Module。

10

Unity WebGL 中文文檔 Unity 2018.1.b
1. WebGL
2. webGL Browser Compatibility
3. Building and running a WebGL project
4. WebGL: Deploying compressed builds
5. Debugging and trouble shooting WebGL builds
6. WebGL Graphics
7. WebGL Networking
8. Using Audio In WebGL
9. WebGL performance considerations
10. WebGL: Interacting with browser scripting
11. Using WebGL Templates
12. Cursor locking and full-screen mode in WebGL
13. Input in WebGL

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 30,240評論 8 265
  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,557評論 0 13
  • This article is a record of my journey to learn Game Deve...
    蔡子聰閱讀 4,123評論 0 9
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評論 19 139
  • 每周回家,總是聽到媽媽抱怨,指責(zé)這個不好,那個不好,心里煩,爸爸不愿意聽她講,她就和我們講一件事可以講十遍,我實在...
    梁耀之閱讀 2,945評論 0 0

友情鏈接更多精彩內(nèi)容