Unity中集成Lua初探

Unity中集成Lua已经几乎成为各游戏公司开发3D游戏的标配,这里对相关知识做个小结。

先说下Unity中使用Lua的优势。这个在网上有很多讨论[1]。主要好处就是可以热更新,因为让玩家更新一个整包的代价非常大,除了王者荣耀这样霸气的游戏,几乎没有哪个中小厂商的游戏能承受因更新整包导致的玩家流失。另外,当出现紧急线上bug时,热更新能保证问题及时修复,相比之下通过iOS或者安卓商店重新提包这个流程上就不知慢多少了。

Unity中使用Lua,一个问题是Lua作为脚本语言本身执行的效率较低,另外还由宿主语言C#来调用,这个过程进一步降低了效率。所以游戏开发前要有规划,一般来说执行频繁、改动少、性能影响大的逻辑(如地图中人物移动、摇杆操作)适合放在C#中,反之则适合放在Lua中。当然有的模块不是那么好判断,需要自己斟酌,如战斗技能这块,按道理来说会经常改动,适合放在lua中,但是据说王者荣耀为了性能考虑是放在C#中。对于C#+Lua的性能优化,网上有很多探讨[2],这里不再深入讨论。

Unity使用Lua的另一个问题是开发效率不如C#。C#作为强类型语言和Unity官方的脚本语言,有VS这样方便的开发工具,编译检查和代码补全功能也非常完善。Lua作为动态脚本语言,入门容易精通难,特别是缺少类型的提示,无论是阅读别人代码还是出错调试都不容易。

因此选择一个好的IDE非常重要。目前Unity+Lua主流的开发工具有[3]:

  1. IDEA+EmmyLua:EmmyLua是基于IntelliJ IDEA的插件,开源免费,支持代码提示、语法检查、引用查找等功能。一个亮点是可自定义变量或函数的类型注解,这样在调用时会按照类型来提示。
  2. LuaStudio:看到很多人说好用,不过是收费的,没有具体研究。
  3. VsCode+LuaIde:VsCode是本人一直在用的代码编辑器,轻量级插件式扩展方便。LuaIde[4]是VsCode的插件,有免费和收费两个版本。可支持代码提示和调试的功能。大致看了一下,感觉配置较为麻烦,没有深入研究下去。

随便说一句,Lua代码规范也很重要。有句话说得好:“程序首先是要让人阅读的,附带着能在机器上运行”。好的Lua函数、变量命名,最好能让人一眼看出作用和类型,这样也省去了利用IDE去追根溯源地查找。

再说下目前主流的Unity+Lua框架[5]。比较成熟的有两种:toLua和sLua。toLua是由以前的uLua发展过来的,总体来说toLua和sLua性能相差不大,toLua似乎稍好一些[6]。本人项目中使用的也是toLua。另外还有一个后来者xLua,是腾讯开源的内部工具,特点是:平时用C#开发,热更新时用Lua hotfix。基本原理是:通过在C#类中打hotfix标签,xLua在il层面注入代码,从而切向Lua的适配函数。一个挺有意思的产品,兼顾开发效率和热更新的便利,关于它的优缺点的详细讨论见这里[7]。

最后以toLua为例,对Unity集成Lua框架的流程做个介绍,只求一个感性认识,不求深入细节。

项目搭建步骤:
1. clone官方库[8]
2. 新建unity工程
3. 依次把官方库里的Assets和Unity5.x/Assets拷贝到项目Assets里
4. 在Examples目录下运行例子

这里着重说说第12个例子GameObject:在场景中不停生成粒子效果。它涉及到C#和Lua的相互调用,比较典型。
启动对象是TestGameObject.unity,它下面挂载TestGameObject.cs脚本:
Unity中集成Lua初探_第1张图片
在Start方法中,重点是下面三行,为由C#调Lua必须执行的起始代码:
lua = new LuaState();
lua.start();
LuaBinder.Bind(lua);

其中,第一行创建一个LuaState对象,是为一个Lua虚拟机;第二行底层是加载了tolua.lua脚本,其中加载了toLua重写的一些Unity性能有问题的类型;第三行是向Lua虚拟机注册所有的wrap类。wrap类是指toLua对CLR和Unity类预生成的文件,Lua通过wrap类间接调用CLR对象,可以提高性能。
最后一行执行script脚本:
Unity中集成Lua初探_第2张图片
可以看到,在Lua脚本里调用GameObject等C#对象也很方便。
这样我们就通过ToLua实现了在Unity游戏中C#和Lua相互调用的一个例子。对于ToLua启动细节这里还有进一步的分析[9],这里不再赘述。

你可能感兴趣的:(unity)