到今天为止,项目已经上线一个多月了,目前稳定运行,各种 bug 也是有的。至少得到了苹果的两次推荐和 TapTap 一次首页推荐,也算是结项后第一时间对我们项目的一个肯定。

  出于各种各样的可描述和不可描述之原因,我们现在需要把项目移植到 Web 端,第一次被告知这个需求时我直接给出了不可能的答复,之前从来没有考虑过这个平台的兼容性,现在项目算是做完了结果要这样折腾一番我觉得是需要消耗非常可怕的人力物力但未必能有很好的效果,性价比很低,但是最终我还是妥协了,硬着头皮接下来,也硬着头皮上,毕竟,技术依然是为了市场和商业服务。
  既然接下了这个活儿(很不情愿的),那就得开始寻找方案,运营方提出使用 Unity 已经放弃维护的 WebPlayer,这个方案我们内部商讨后决定放弃,直接奔向 WebGL。
  在记录这些文字时,我尚未完全解决所有的基础问题,也许最终无法通过或者受限于技术能力而夭折,但是通过这些记录也许能帮到后面想要踩这些坑的人。
  查找了 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 出来,效率问题都先不考虑。

  先从 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)/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 部分已完成,可以往下走了。

关于 Unity WebGL 的探索(一)的更多相关文章

  1. 关于 Unity WebGL 的探索(二)

    关于 Unity WebGL 的探索(二) 上一篇博客记录了关于 WebGL 移植的第一步:部分 C/C++ 插件的编译,目前项目中的部分插件使用该方法通过,接下来比较大的一部分工作量是网络模块 We ...

  2. Unity WebGL 窗口自适应

    unity 打包好WebGL后,用文本编辑器编辑打包生成的 index.html 文件 在生成的html里面修改代码     <script type="text/javascript ...

  3. Unity WebGL MoonSharp崩溃问题

    当前Unity的代码更新方案基本都选择的ULua,而我们项目还需要考虑Web平台,ULua不支持WebGL,所以决定选择MoonSharp.MoonSharp(http://www.moonsharp ...

  4. Unity WebGL请求Http接口出现的Cors跨域问题

    1.运行环境 (1)WebGL运行浏览器:Firfox Quantum 67.0(64位) (2)服务端API运行环境:IIS,.Net Core 2.1 API 2.问题:CORS 头缺少Acces ...

  5. Unity WebGL WebSocket

    在线示例 http://39.105.150.229/UnityWebSocket/ 快速开始 安装环境 Unity 2018.3 或更高. 无其他SDK依赖. 安装方法 通过 OpenUPM 安装 ...

  6. Unity WebGL

    路过弄了个unity Unity导出WebGL不支持c#socket和unity的network 可以用javascript的websocket实现... c#一般通过www从phpserver获取. ...

  7. Unity发布WebGL时如何修改默认的载入进度条

    Unity发布WebGL版本后,需要去除Unity的Logo,首先关闭Splash Image去除Made with Unity启动画面(在File->Build Settings->Pl ...

  8. Unity发布WebGl注意事项

    unity 版本是5.5,不过看了2017的文档好像也是差不多,绝大部分都是根据官方文档,希望有帮助,如果有错误或者你知道更多这方面的只是,请告知下,大恩言谢. 1:对webgl发布的工程文件说明   ...

  9. 【Unity】开发WebGL内存概念具体解释和遇到的问题

    自增加unity WebGL平台以来.Unity的开发团队就一直致力于优化WebGL的内存消耗. 我们已经在Unity使用手冊上有对于WebGL内存管理的详尽分析,甚至在Unite Europe 20 ...

随机推荐

  1. ClassCastException: org.apache.tomcat.websocket.server.WsServerContainer cannot be cast to javax.websocket.server.ServerContainer

    21:09:22.221 [MessageBroker-3] INFO c.t.s.s.impl.StockNewsServiceImpl - [2017-12-16 21:09:22] execut ...

  2. 基本控件文档-UIKit结构图---iOS-Apple苹果官方文档翻译

    本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址  UIKit结构图 //转载请注明出处--本文永久链接:http://www.cnbl ...

  3. iOS多线程 iOS开发Demo(示例程序)源代码

    本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址(2013年12月29日更新版)   iOS程序源代码下载链接:01.大任务.zip22 ...

  4. SQL Server Delete Duplicate Rows

    There can be two types of duplication of rows in a table 1. Entire row getting duplicated because th ...

  5. Linux 内核通知链随笔【中】【转】

    转自:http://blog.chinaunix.net/uid-23069658-id-4364171.html 关于内核通知链不像Netlink那样,既可以用于内核与用户空间的通信,还能用于内核不 ...

  6. Ubuntu终端里面显示路径名称太长,怎么设置变短【转】

    转自:http://blog.csdn.net/id19870510/article/details/8276914 $: sudo vi ~/.bashrc 这个文件记录了用户终端配置 找到 if ...

  7. tiny-rtems-src

    https://github.com/RTEMS/rtems-libbsd https://github.com/freebsd/freebsd/tree/642b174daddbd0efd9bb5f ...

  8. MVC 从控制器将数据对象赋值给前端JS对象

    @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...

  9. XCopy复制文件夹命令及参数详解以及xcopy拷贝目录并排除特定文件

    XCOPY是COPY的扩展,可以把指定的目录连文件和目录结构一并拷贝,但不能拷贝系统文件:使用时源盘符.源目标路径名.源文件名至少指定一个:选用/S时对源目录下及其子目录下的所有文件进行COPY.除非 ...

  10. Kotlin 学习使用之旅(二)

    为什么从二开始呢?再此之前已经有了一篇了,那是刚知道kotlin的时候草(chao)来(chao)的并且学习一篇, 这次是自己在项目中正式使用并且遇到的一些问题记录,供kotlin新入门的童鞋参考,避 ...