关于 Unity WebGL 的探索(一)

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

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

时间: 2024-10-30 07:20:04

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

unity webgl获取跳转页面的url信息

需求的这样的  客户端用webgl开发 但登陆界面是 普通的html页面 比如 你登陆百度后跳转到unity webgl页面 因为http的无状态无连接的性质  所以需要我们使用地址栏传递下登陆的信息到游戏界面 惯例 上代码(滴滴 开车了) ? 1 2 3 4 5 6 7 [DllImport("__Internal")]  private static extern string StringReturnValueFunction();  public static string U

Unity WebGL 窗口自适应

unity 打包好WebGL后,用文本编辑器编辑打包生成的 index.html 文件 在生成的html里面修改代码     <script type="text/javascript">      function Reset() {   var canvas = document.getElementById("#canvas"); canvas.height= document.documentElement.clientHeight;   can

Unity WebGL 取消浏览器警告

1.浏览器支持 https://docs.unity3d.com/Manual/webgl-browsercompatibility.html 2.可用方案 1 using System; 2 using System.IO; 3 using System.Text.RegularExpressions; 4 using UnityEditor; 5 using UnityEditor.Callbacks; 6 7 public class PostBuildActions { 8 [PostP

Unity,WebGL, 页面JS调用Unity方法

与WebPlayer类似,在JS中用SendMessage 比如在Unity场景中有一个GameObject,叫A,A上有C#脚本,里面有个方法 public void F(string str) { //do something... } 在发布出的WebGL项目index.html中用JS调用此方法 <script> var gameInstance = UnityLoader.Instantiate("gameContainer", "Build/WebAn

【Unity】开发WebGL内存概念详解和遇到的问题

自加入unity WebGL平台以来,Unity的开发团队就一直致力于优化WebGL的内存消耗.我们已经在Unity使用手册上有对于WebGL内存管理的详尽分析,甚至在Unite Europe 2015与Unite Boston 2015两届大会上,也有专题对其进行深入的讲解.然而,这方面的内容依旧是用户讨论的热门话题,因此我们意识到应当分享更多.希望本文能回答一些被频繁咨询的问题. Unity WebGL与其它平台有何不同? 一些用户已经熟悉了部分内存有所限制的的平台.而对于其它如桌面和Web

构建WebGL目标时的内存考量

Memory Considerations when targeting WebGL 构建WebGL目标时的内存考量 Memory in Unity WebGL can be a constraining factor restricting the complexity of the content you can run, so we would like to provide some explanation on how memory is used in WebGL. 对于Unity

WebGL开发入门

­­­Getting started with WebGL development WebGL开发入门 What is Unity WebGL? 什么是Unity WebGL? The WebGL build option allows Unity to publish content as JavaScript programs which use HTML5 technologies and the WebGL rendering API to run Unity content in a

基于SuperSocket实现的WebSocket服务器 和Unity中使用Websocket

孙广东  2016.10.15 http://blog.csdn.NET/u010019717 说一下 Unity客户端的库: 1.websocket-sharp  AS中已经下架了,  https://github.com/sta/websocket-sharp  但是Unity的官方插件 :  Simple Web Sockets for Unity WebGL   就是使用的它 2.Simple Web Sockets for Unity WebGL(推荐)  Unity官方退出的插件 3

Unity_WebGL相关

先说个题外的ajax遇到跨域问题(我用jquery) $.ajax({ url:url, dataType:"jsonp", type:"GET", success:function(msg) { //...... } }); 要用jsonp和get在ajax请求后获得的数据,用JSON.parse来转换json,如果报错了,那有可能是传过来的数据里有非法字符,比如中文符号之之类的 再次总结一下Unity WebGL下C#与JS交互一些基本 一.从页面上用js调取U