1. 程式人生 > 實用技巧 >WebGL 內嵌網頁的一種解決方案

WebGL 內嵌網頁的一種解決方案

  之前使用的 ZFBrowser 嵌入方案可以釋出到 Win, OS, Linux 上, 可是其它的就不行, 因為它用的谷歌核心嘛, 在 WebGL 上照理來說應該是最方便的啊, 因為它本身就是執行在瀏覽器核心上的, 前面的 BrowserInput 已經研究過向網頁注入程式碼以及呼叫了, 現在試試在 WebGL 環境下來注入程式碼, 來建立簡單的內嵌網頁看看.

  Unity2017之前的方法跟 ZFBrowser 的很像, 用起來很方便, 可是以後會被禁用 :

[Obsolete("Application.ExternalEval is deprecated. See https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html for alternatives.
")] public static void ExternalEval(string script); [Obsolete("Application.ExternalCall is deprecated. See https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html for alternatives.")] public static void ExternalCall(string functionName, params object[] args);

  也不知道他們咋想的, 官方給的新方法是寫一個 XXX.jslib 檔案, 裡面寫的程式碼就是注入形式的程式碼, 通過[DllImport("__Internal")] 的方式引用方法, 感覺就是編譯成C++程式碼了, 先不說它效率高不高, 單是一個使用上就很蛋疼了啊, 看看一個 .jslib 檔案, 官方的 :

mergeInto(LibraryManager.library, {

  HelloString: function (str) {
    window.alert(Pointer_stringify(str));    // unity傳過來的string, 需要進行轉換才能作為瀏覽器字串
  },

  PrintFloatArray: function (array, size) {  // 陣列還要自己傳遞長度
    for(var i = 0; i < size; i++)
    console.log(HEAPF32[(array >> 2) + i]);    //
float[] 陣列, 這樣轉換夠奇葩了 }, StringReturnValueFunction: function () { var returnStr = "bla"; // 網頁字串 var bufferSize = lengthBytesUTF8(returnStr) + 1; var buffer = _malloc(bufferSize); stringToUTF8(returnStr, buffer, bufferSize); return buffer; // 傳遞給Unity的字串經過轉換才能傳遞... }, });

Unity 呼叫 :

    [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 string StringReturnValueFunction();
    
    void Start()
    {
        HelloString("This is a string.");            // 傳遞string給WebGL

        float[] myArray = new float[10];
        PrintFloatArray(myArray, myArray.Length);    // 傳遞Array給WebGL, 長度也要傳...

        Debug.Log(StringReturnValueFunction());      // 從WebGL獲取字串
    }    

  這樣反人類的做法, 估計是不能成事的了, Unity走了一條歪路......

  不管怎樣順著來吧, 就是注入一個建立 iframe 的程式碼, 讓它能夠顯示在 Unity 的視窗範圍之內, 如果成功的話, 加上自動跟隨和縮放功能, 它就是半個嵌入式網頁了, 因為它只能實現最上層顯示, 不能像 ZFBrowser 那樣嵌入 UI 或是任意 Mesh 上顯示, 沒有真正的遮擋.