關於 Unity WebGL 的探索

轉自:https://www.cnblogs.com/yaukey/p/unity_webgl_explore_1.html

查找了 Unity 的官方資料,我們如果需要使用 WebGL 需要面對以下幾個挑戰:

  1. Native Plugin:也就是說各種原生插件(C/C++等編譯的本地機器碼庫),我們的挑戰是使用了 SLua。
  2. 多線程:WebGL 端無法支持任何多線程代碼,因爲 JavaScript 沒有多線程的實現,C# 端使用的類似 System.Threading 等庫最終都不會被編譯成相應的 js 代碼。
  3. 網絡模塊:傳統的 Socket 無法使用,必須使用 WebSocket 或者 xxx,System.Net,尤其是 UnityEngine.Net.Sockets 都未在 WebGL 端實現,所以將無法被正確編譯轉換;Unity 中可以使用 WWW 和 UnityWebRequest,或者使用新版支持 WebGL 的 Unity Networking API;或者直接在 JavaScript 中使用 WebSockets 和 WebRTC 來實現網絡層功能。
  4. 渲染:WebGL 的圖形 api 是基於 OpenGL ES 2.0;GI 只支持 Baked GI(我們沒使用);Procedural Materials 不支持(我們沒使用);Linear Rendering 不支持(我們沒使用);MovieTextures 不支持(我們沒使用);WebGL Shader code restrictions:目前理解爲在 shader 代碼中只支持使用常量,循環的索引值或者聯合體來作爲訪問數組和矩陣的索引,唯一的例外是在 Vertex Shader 中訪問 uniform 時可以使用任意的表達式,另外還有循環的限制,不可以使用 “計數循環-初始化一個變量時賦給一個常量值,每次循環時增加或減少一個常量值” 以外的方式,並且不支持 while 循環。(目前大致看來我們沒有使用數組或矩陣的下標表達式,也沒有使用複雜的循環,後期可能還需要仔細排查)。
  5. Audio 有幾乎一大半的 api 不支持,後面需要做兼容修改,應該不少麻煩。
  6. 其它暫不考慮,以上幾項直接決定我們是否可以先 Port 出來,效率問題都先不考慮。
  7. 先從 Native Plugin 入手,Lua 這是需要邁過的第一道坎兒。官方給了兩個很好的文檔:WebGL: Interacting with browser scripting 和 Unity WebGL中的底層插件,WebGL 是通過 IL2CPP 將所有的 C# 代碼轉換成 C++,這樣便可以使用基於 LLVM 的 Emscripten 的工具鏈將所有的 C++ 代碼編譯成基於 asm.js 的 JavaScript 代碼,這樣便可以在支持 Html5 的瀏覽器上運行。

      我們使用了 SLua 插件,所以我現在需要使用 Lua 的源代碼來參與編譯和打包過程即可。很慶幸我們項目在今年大家開會討論後決定從原來的 LuaJit 升級爲 Lua 5.3,如果是 LuaJit 項目本身的編譯產生了大量針對目標平臺的彙編代碼來最終生成的,具有極大的平臺特異性,所以就算是使用 LuaJit 的源碼也是無法使用 WebGL 的,依然需要直接使用 Lua 5.1 或者 5.3 的源碼。

      新建一個空的 Unity 工程,導入 SLua 插件,切換到 WebGL 平臺,在 Plugins 中新建文件夾 WebGL,新建一個 C 代碼文件比如:lua.dll.c,然後將最新版 Lua5.3 源碼解壓到本地的一個目錄:(LuaSrcDir),所有代碼都在(LuaSrcDir),所有代碼都在(LuaSrcDir)/src 中,將 slua.c 也拷貝進來,但是要排除 lua.c,luac.c 這兩個文件。

      在 lua.dll.c 中加入以下內容:

    複製代碼

    #define LUA_COMPAT_5_1
    #define LUA_COMPAT_5_2
    
    // Lua source code only, relative .
    #include “$(LuaSrcRelativePath)/src/lapi.c”
    #include “$(LuaSrcRelativePath)/src/lauxlib”
    #include “$(LuaSrcRelativePath)/src/lbaselib.c”
    …
    // Add all lua source file *.c, exclude lua.c, luac.c.
    //#include "$(LuaSrcRelativePath)/src/lua.c"
    //#include "$(LuaSrcRelativePath)/src/luac.c"
    
    #include “$(LuaSrcRelativePath)/src/slua.c”

    複製代碼

      注意:以上所有內容都是添加 Lua 的源文件,不包括頭文件,具體開頭使用要使用哪些預編譯宏,取決於你的項目。

    另外由於 Lua 5.3 向下兼容的問題,如果定義了 LUA_COMPAT_5_1後,LUA_COMPAT_MODULE 會被定義,那麼就會編譯兼容實現:luaL_findtable,而 SLua 中爲了兼容多寫了一份,所以這時候可以刪掉 slua.c 中的實現,否則編譯會出現重定義的錯誤。

      接下來在 Unity Player Setting 中加入預編譯宏 LUA_5_3 將 SLua 切換到 5.3 的實現版本,然後就直接將某個示例場景添加的構建列表,BuildAndRun,就可以看到 SLua 的 Demo 場景正確的運行在瀏覽器上了。

      至此,Lua 的 Native Plugin 部分已完成,可以往下走了。

發佈了64 篇原創文章 · 獲贊 94 · 訪問量 38萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章