纳金网

标题: unity各平台热更新方案 [打印本页]

作者: kuaidaoshou    时间: 2018-8-28 08:39
标题: unity各平台热更新方案
鸣谢:Burnner

一、不同平台热更新的比较
Android 应用的热更新将执行代码预编译为assembly dll
将代码作为TextAsset打包进Assetbundle
运行时,使用Reflection机制实现代码的功能。
更新相应的Assetbundle即可实现热更新。

Android 与iOS 热更新的异同 苹果官方禁止iOS下的程序热更新;JIT在ios下无效。
热更新方案:Unity+Lua插件
二、热更新的各种Lua 插件的对比3.1、uLua(asset store)•  uLua插件原生版本,开山鼻祖
•  不会产生静态代码
•  反射机制,效率低下,速度慢,gc alloc频繁
•  已停止更新维护,不支持Unity5.x,淡出主流
3.2、XLua(腾讯2017年开源的手游热更新方案)开发只用C#
运行也是C#,性能可以秒杀lua
出问题了才用Lua来改掉C#出问题的部位,替换甚至做到不用重启游戏;
补丁需要预打入
开头加入几个il指令对性能的开销
开源项目地址
https://github.com/Tencent/xLua
3.2uLua & cstoLua(合并后叫做toLua•  开发平台成熟稳定,Bug修复迅速
•  开发者众多,资源丰富
•  静态方法,性能优
有成功商业产品案例(啪啪三国、超神战队、酷鱼吧捕鱼、绝地战警、这不是刀塔等)
•  都是基于原生版本的改进;未来,两者会合并成一个插件
开源项目地址:
https://github.com/topameng/tolua
3.3、sLua•  静态方法,性能优
•  核心代码简洁
•  资源较少,开发平台不够成熟稳定
•  无成功商业产品案例成功商业产品案例
•  基于原生版本的改进
开源项目地址:
https://github.com/pangweiwei/slua
3.4、C#Light(L#)淡出主流,想要了解的小伙伴点击这里:
https://github.com/lightszero/LSharp
3.5、 uniLua• c#实现的Lua虚拟机,非完整方案
淡出主流
三、使用Lua 插件进行 热更新的总体流程
综合上面这些热更新插件的分析跟对比,比较可靠跟稳定的热更新方案一个是腾讯的xLua热更新框架。一个是uLua+cstoLua结合的toLua框架。接下来就对这两个框架进行具体的分析。
以上的参考:
http://blog.csdn.net/guofeng526/article/details/52662994
http://www.cnblogs.com/muyuqianshan/p/6937096.html
四、Xlua热更新方案分析
项目地址:https://github.com/Tencent/xLua
4.1 Unity热更新遭遇的问题目前Unity下的热更新方案有不少,这些方案都要求要热更新的地方一开始就得用脚本来实现,这带来一些问题:
1、接入成本高,有的项目已经用C#写完了,这时要接入需要把需要热更的地方用脚本重新实现;
2、即使一开始就接入了,也存在同时用两种语言开发难度较大的问题,有些项目只是想fixbug而已,却被迫使用两种语言开发,明显代价有点大;
3、脚本性能不如C#
4.2、xlua的更新方案思路(另类Unity热更新大法:代码注入式补丁热更新 之前的unity热更新的方案都是在需要热更新的地方通过c#调用lua来实现热更新的。因而或多或少的会遭遇到4.1所说的三个问题。毕竟C#是一门编程语言,它运行之前需要进行编译,而这个编译的过程在移动平台无法完成,所以当我们游戏的逻辑更改,C#代码发生改变的时候,我们就需要重新在开发环境下编译,然后重新打包,然后让玩家去下载更新最新的版本
好像在需要更新的地方也只能选择luajs这样的脚本语言来实现动态加载更新了。看起来好像是最好的解决方案了。但是反观Unity之外有不少方案,比如ios下的jspatchandroid下的tinker等,并没这约束。以jspatch为例,它支持把一个oc函数替换为js实现,平时开发可以只写oc,只有出现bug,才需要写个jsfixxlua就是这样的一个解决方案。

xLua热补丁技术支持在线把一个C#(方法,属性,事件等等)实现替换成Lua实现。这意味着你可以:
1、开发只用C#
2、运行也是C#,性能可以秒杀lua
3、出问题了才用Lua来改掉C#出问题的部位,替换甚至做到不用重启游戏;
用完即走,是小龙哥对一个好工具的定义,xLua这个特性也如此:没问题的时候你感觉不到它的存在,出了问题才需要它来救场。而你只需要在需要热修复的地方打上hotfix标签。
4.3两条指令的性能开销xLua会在C#编译成il后插入一个处理,该处理会从il层面为每个打了Hotfix标签的类型的函数开头加入几个il指令,如果用C#描述是这样的:
public int Add(int a, int b)
{
    return a + b;
}

// 加了il指令:
static Func<object,int,="" int=""> hotfix_Add = null;
public int Add(int a, int b)
{
    if (hotfix_Add !=null) return hotfix_Add(this, a, b);
    return a + b;
}
如果lua中执行了hotfix调用,hotfix_Add会指向一个lua的适配函数。

性能开销:
   如果不打补丁,就一个if判断,比注入前多执行两条很轻量级的指令(Ldsfld,Brfalse),我在window下测试,这两指令加起来仅相当于空函数调用开销的十分之一到五分之一。

内存开销:
    每个函数会多一个静态delegate引用,注意是静态的,和对象实例个数无关。(Stateful方式会略不同,后面单独分析)。

安装包影响:
    一般情况,就一个if和delegate调用。如果泛化函数以及参数含非public类型参数或返回值的函数会多一点:每一个输入参数,每个输出参数,对应一次函数调用,外加三次函数调用。

4.4热补丁支持的C#特性各种函数,包括私有/公有,静态/成员,操作符重载,泛化函数。
  构造函数,析构函数,和普通函数不一样的是,构造函数和析构函数并不是用lua函数替换了,而是执行了lua函数后还会执行原来的逻辑。
  属性,包括私有/公有,静态/成员,泛化的。
  事件的add/remove。
  泛化类型。
  总而言之,目前已知唯一尚不支持的是类静态构造函数。
4.5 xLua的突破xLua在功能、性能、易用性都有不少突破,这几方面分别最具代表性的是:
可以运行时把C#实现(方法,操作符,属性,事件等等)替换成lua实现;
出色的GC优化,自定义struct,枚举在Lua和C#间传递无C# gcalloc;
编辑器下无需生成代码,开发更轻量;

参考:https://github.com/Tencent/xLua
http://gad.qq.com/article/detail/7182056
https://www.zhihu.com/question/54344452

五 toLua热更新方案分析
项目地址:https://github.com/topameng/tolua
5.1 toLua历史版本toLua的衍化版本:uLua(反射时代)->uLua+cstoLua(去反射时代) -> toLua(新一代引擎时代)。
         最早的2004年ulua从国外引进到国内,可以说uLua使得国内的Unity热更新领域被揭开了序幕toLua框架经过了120多个上线商业手机游戏的测试,已经趋于成熟。并且其中腾讯、盛大、巨人、完美、畅游等等众多著名大厂均已经推出基于ulua的名作
       相比于最早的ulua框架,toLua可谓是卷土重来,从高效率、稳定性、代码质量等方面都提升N倍,重写的引擎:代码简洁,逻辑清晰明了,是代码优雅+效率之神完美化身,从此tolua #将代替ulua走上Unity热更新舞台
5.2 toLuatolua#是Unity静态绑定lua的一个解决方案,它通过C#提供的反射信息分析代码并生成包装的类。它是一个用来简化在C#中集成lua的插件,可以自动生成用于在lua中访问Unity的绑定代码,并把C#中的常量、变量、函数、属性、类以及枚举暴露给lua。它是从cstolua衍变而来。从它的名字可以看出,它是集成了原来的tolua代码通过二次封装写了一个C#与tolua(c)的一个中间层。







欢迎光临 纳金网 (http://c-www.narkii.com/club/) Powered by Discuz! X2.5