之前使用的 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走了一條歪路......
PS : 既然注入 JavaScript 這么繞, 那肯定是為了性能了, 看了一下編譯方案, 頻繁出現 Emscripten 這個字眼, 查了一下, 就是這個編譯器, 在編輯器檔案夾下也找到了

不管怎樣順著來吧, 就是注入一個創建 iframe 的代碼, 讓它能夠顯示在 Unity 的視窗范圍之內, 如果成功的話, 加上自動跟隨和縮放功能, 它就是半個嵌入式網頁了, 因為它只能實作最上層顯示, 不能像 ZFBrowser 那樣嵌入 UI 或是任意 Mesh 上顯示, 沒有真正的遮擋.
添加一個創建 iframe 的代碼 :
mergeInto(LibraryManager.library, { CreateIFrame: function () { window.alert("CreateIFrame!!!"); var div = window.document.createElement('div'); div.style.zIndex = "100"; div.style.position="absolute"; window.document.body.appendChild(div); var iframe = window.document.createElement('iframe'); iframe.style.zIndex = "1000"; iframe.style.position="absolute"; iframe.src = "http://XXXX/OOOO/"; div.appendChild(iframe); }, });
Unity 添加呼叫代碼 :
[DllImport("__Internal")] private static extern void CreateIFrame(); void Start() { CreateIFrame(); }
PS : Unity使用的是絕對位置, 反而比較方便進行坐標對齊操作.
運行之后大概是這個樣子, 正常實作了網頁覆寫, 因為原本就是嵌入到Unity的網頁, 網頁背景是透明的 :

要做成嵌入式的感覺, 只需要根據Unity的坐標計算換算到網頁, 設定 iframe 位置 / 縮放 就可以了, 沒什么好說的, 不過因為沒有遮擋關系, 沒有什么實用價值...
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/2034.html
標籤:其他
上一篇:程式猿和程式媛的網戀—作業(五)
