zoukankan      html  css  js  c++  java
  • 【腾讯Bugly干货分享】手游热更新方案xLua开源:Unity3D下Lua编程解决方案

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/2bY7A6ihK9IMcA0bOFyB-Q

    导语

    xLua是Unity3D下Lua编程解决方案,自2016年初推广以来,已经应用于十多款腾讯自研游戏,凭借其出色的性能,易用性,扩展性而广受好评。

    而就在前天,腾讯宣布xLua开源到github上,引起了游戏开发圈的轰动,今天精神哥就来给大家介绍——手游热更新方案 xLua。

    xLua项目1月3日起正式对外开源

    官方开源地址:
    https://github.com/Tencent/xlua
    (点击文末阅读原文,直接访问该项目)

    xLua的几项突破

    xLua在功能、性能、易用性都有不少突破,这几方面分别最具代表性的是:

    1. Unity3D全平台热补丁技术,可以运行时把C#实现(方法,操作符,属性,事件,构造函数,析构函数,支持泛化)替换成lua实现;
    2. 自定义struct,枚举在Lua和C#间传递无C# gc alloc;
    3. 编辑器下无需生成代码,开发更轻量;

    初探xLua

    xLua设计原则是保证了运行效率的前提下,尽量的保证开发效率。是不是简单易用,看了下面的例子你说了算,性能好不好,实际测试说了算。

    三行代码跑lua脚本

    一个完整的例子仅需3行代码:

    下载xLua后解压到Unity工程Assets目录下,建一个MonoBehaviour拖到场景,在Start里头加上这么三行:

    XLua.LuaEnv luaenv = new XLua.LuaEnv();
    luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')");
    luaenv.Dispose();
    

    运行就可以看到Console打印的hello world。

    1. 第一和第三行分别LuaEnv的创建以及销毁,所谓LuaEnv可以理解为lua虚拟机,往往整个工程一个虚拟机即可;
    2. DoString里头可以是任意合法的lua代码,例子中调用了UnityEngine.Debug.Log接口打印了一个log(C#的静态函数在CS下直接可用);

    C#调用lua系统函数math.max

    xLua支持把一个Lua函数绑定到C# delegate。
    我们先声明一个delegate,并为它加上CSharpCallLua标签:

    [XLua.CSharpCallLua]
    public delegate double LuaMax(double a, double b);
    

    然后在上面那例子加上这么两行(luaenv销毁前):

    var max = luaenv.Global.GetInPath<LuaMax>("math.max");
    Debug.Log("max:" + max(32, 12));
    

    就那么简单,把lua的math.max绑定到C#的max变量后,调用就和一个C#函数调用差不多了,而且,最最重要的是,执行了"XLua/GenerateCode"后,max(32, 12)调用是不产生(C#)gc alloc的,既优雅,又高效!

    更详细的可以看XLuaDoc下的文档。

    热补丁技术

    xLua支持热补丁,这意味着你可以:

    1. 开发只用C#;
    2. 运行也是C#,性能可以秒杀lua;
    3. 出问题了才用Lua来改掉C#出问题的部位,下次整体更新时换回正确的C#,能做到用户不重启程序fix bug;

    把易用性进行到底

    xLua的易用不仅仅体现在编程,还体现在方方面面的细节考虑,甚至考虑到团队配合工作流。

    xLua菜单就两个,分别是生成代码和清除生成代码。

    还能更简单些么?还能!

    上面两个菜单你开发期间甚至都不用管,要build手机版本前执行一下“GenerateCode”就可以了(这也有API可集成到项目的自动化打包流程)。

    这就是xLua的特色功能之一:编辑器下无需生成代码支持所有特性。

    之所以做这个功能,是因为有的项目反馈,“生成代码”对于策划美术太高大上了一点,教了很久还是老忘;还有个大项目反馈说由于代码很多,每次生成代码后,Unity菊花都要转很久。

    想项目所想,急项目所急本是我辈风范,就做了,尽管挺麻烦的。

    无缝支持生成代码及反射

    生成代码固然重要,已然是各大主流方案的标配。

    反射有的方案明确不支持,但从项目的反馈来说,也是至关重要的:有的项目代码很多,已经接近苹果的80M Text段的限制,对他们来说,代码量大小关乎到能否发布,反射方式性能不如生成代码,但对安装包影响小。

    这的无缝有两个含义:

    1. 两者在支持的特性以及特性的使用方式都是一致的,两者方式间切换,业务逻辑代码不用修改,改改配置就可以了;
    2. 两者无缝配合,比如一个继承链上,任意一个类都可以选择生成代码或者反射,比如子类选择生成代码,父类由于不常用选择了反射,还是可以在子类对象上调用父类的方法;

    对于il2cpp的stripping,xLua也考虑到了,只要你对一个类配置了ReflectionUse,会自动生成Unity的link.xml配置文件,将该类型列为不剪裁。

    关于性能

    作为一个基础库,性能是至关重要的,其中又有一项指标是大家极为关注的:C#侧的gc alloc,xLua在这块做了不少创新。

    正如前面例子所示,xLua支持把一个Lua函数绑定到一个C# delegate,这可以避免值类型在参数传递时产生的gc。

    另外,在复杂值类型表达方面,xLua也取得相当突破。只要一个struct只包含值类型,配置了GCOptimize后,其参数传递,数组访问无gc。

    所有枚举,配置了GCOptimize后无gc;

    更多无GC的用法可以参见配套的例子(XLuaExamples5_NoGc)。

    不仅仅GC优化这块,Lua和C#间相互调用性能也可圈可点,具体可以关注我们发出的性能测试报告。

    PS:我们的性能测试没有用网上流传较广的那套用例。我们认为其并不合理:

    1. 测试Lua调用C#部分用例选择了Vector3,这其实是错误的,市面上大多方案的Vector3是完全在Lua测重新实现,完全没有达到测试“Lua调用C#”的目的;
    2. 测试全部用Unity API做测试,这并不合理,Unity API本身的开销会影响到测试结果。举个例子:方案A的Lua调用C#函数开销是1ms,方案B是2ms,那么结论应该是A方案性能是B方案两倍,但如果被调用C#函数本身耗时100ms,那结论就是两个方案性能差不多,甚至有时会因为误差得出B方案性能更好的结论。

    更合理的做法是用空负荷的类型(函数是空的,property,event等也不要有运算开销),xLua所有测试用例都是基于这个原则。

    扩展性

    开发中我们往往要用到很多东西,比如用PB和后台交互,解析json格式的配置文件等等。虽说我们都可以在C#那找到相应的库,然后通过xLua去使用这些库,但这效率不高,最好能有相应Lua的库。

    不少方案是直接集成一些常用的Lua库,但这带来些新问题:

    1. 这些库不一定用到,却增大安装包;
    2. 集成的库也不一定符合项目习惯:json解析有人喜欢rapidjson,有人爱用cjson,所谓众口难调;
    3. 对于某些项目,这些库还是不够,还是得自己去想办法加;

    我们的原则是授之以鱼,不如授之以渔,xLua在这方面的支持是:

    1. 提供了接口,教程,让大家可以不修改xLua代码就可以加入自己喜欢的库;
    2. xLua用cmake实现跨平台编译,大家可以选择伴随xLua一起编译,修改一个makefile文件,搞定各平台编译。

    除了很方便加入第三方Lua插件,xLua的生成引擎支持二次开发,可以编写生成插件,生成自己所需的一些代码,配置。

    后续持续支持

    用开源,最怕碰到情况是:作者已“死”,有事烧香。“死”主要是说不维护了,可能是作者太忙,或者没兴趣了,或者写着写着感觉进入一个死胡同,重构(做)了个完全不一样的版本,原来版本直接抛弃等等。

    用xLua就没这方面的担心,大公司支持,开发,测试,答疑都有全职的团队。腾讯自己都有很多项目在使用呢。

    版本开发流程很正规,较大版本会做一次主流机型的适配测试,用着就放心。

    总结一下

    xLua推广以来,用心倾听应用项目的需求,在易用性,性能,扩展性等方面得到长足的进步,开源后也将会继续秉承这个这原则,做一款有诚意的库。


    更多精彩内容欢迎关注腾讯 Bugly的微信公众账号:

    腾讯 Bugly是一款专为移动开发者打造的质量监控工具,帮助开发者快速,便捷的定位线上应用崩溃的情况以及解决方案。智能合并功能帮助开发同学把每天上报的数千条 Crash 根据根因合并分类,每日日报会列出影响用户数最多的崩溃,精准定位功能帮助开发同学定位到出问题的代码行,实时上报可以在发布后快速的了解应用的质量情况,适配最新的 iOS, Android 官方操作系统,鹅厂的工程师都在使用,快来加入我们吧!

  • 相关阅读:
    Leetcode Reverse Words in a String
    topcoder SRM 619 DIV2 GoodCompanyDivTwo
    topcoder SRM 618 DIV2 MovingRooksDiv2
    topcoder SRM 618 DIV2 WritingWords
    topcoder SRM 618 DIV2 LongWordsDiv2
    Zepto Code Rush 2014 A. Feed with Candy
    Zepto Code Rush 2014 B
    Codeforces Round #245 (Div. 2) B
    Codeforces Round #245 (Div. 2) A
    Codeforces Round #247 (Div. 2) B
  • 原文地址:https://www.cnblogs.com/bugly/p/6264772.html
Copyright © 2011-2022 走看看