到今天为止,项目已经上线一个多月了,目前稳定运行,各种 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. jQuery简单的Ajax调用

    index.php 的代码如下: <!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"& ...

  2. Asp.Net Web Forms/MVC/Console App中使用Autofac

    本来简单介绍了Autofac在Asp.Net Web Forms中的应用,后来又添加了mvc.控制台应用程序中使用Autofac,详情请看源码. ASP.NET Web Forms使用Autofac, ...

  3. Morley's Theorem (计算几何基础+向量点积、叉积、旋转、夹角等+两直线的交点)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  4. Eclipse连接海马模拟器

    找到海马模拟器安装目录: 使用cmd 命令进入命令行:D: cd:D:\Program Files (x86)\Droid4X 进入模拟器所在目录 运行adb connect 127.0.0.1:26 ...

  5. @EnableEurekaClient源码分析

    @EnableEurekaClient注解,从源码的角度分析是如何work的 NetFlix Eureka client Eureka client 负责与Eureka Server 配合向外提供注册 ...

  6. js中的return

    retrun true: 返回正确的处理结果. return false:分会错误的处理结果,终止处理. return:把控制权返回给页面(如果条件满足,后面的逻辑就不执行了). if(this.in ...

  7. vim查找/替换字符串【转】

    转自:http://www.cnblogs.com/GODYCA/archive/2013/02/22/2922840.html vi/vim 中可以使用 :s 命令来替换字符串.该命令有很多种不同细 ...

  8. C语言将字符串转换成对应的数字(十进制、十六进制)【转】

    转自:http://wawlian.iteye.com/blog/1315133 问题1:讲一个十进制数字的字符串表示转换成对应的整数.举例:将“”转换成整数1234. C代码 收藏代码 /*将字符串 ...

  9. ASP.NET MVC 文件上传

    如果想要用HTML表单实作文件上传的功能,那么必须在输出的<form>表单标签加上一个enctype属性,且内容必须设定为multipart/form-data,要通过Html.Begin ...

  10. HDU 6186 CS Course 前缀和,后缀和

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6186 题意:给了n个数,然后有q个查询,每个查询要求我们删掉一个数,问删掉这个数后整个序列的与值,或值 ...