初学ULua与XLua,在这里简单介绍一下各自特点与使用步骤,若有不当之处,欢迎指正。
一:介绍
ULua与XLua都是用于Unity项目的热更新。
ULua的集成开发环境为SimpleFramework,分为NGUI版和UGUI版。实际上,ULua是对Lua的一次“包装”,而SimpleFramework是对ULua的又一次“包装”。由此可知,其关系为SimpleFramework>ULua>Lua。ULua本身已经写好了框架,需要开发者在游戏的开发阶段就要确定好哪些部分需要使用Lua脚本编写,这样如果在游戏发布以后发现了Bug,或者需要更新部分内容,可以很方便地进行热更新。
而XLua是腾讯的一个开源项目,它在开发阶段十分便捷,脚本可以都用C#来编写,但是若想进行热更新是十分麻烦的,可能很小的地方需要在Lua脚本重写大量的代码。
二:使用步骤
①ULua(此处以NGUI版本为例)
1.将SimpleFramework载入Unity项目。而SimpleFramework是在Unity5.0.0版本下打包的,当用更高项目的Unity时需要对项目进行”Upgrade”。API的升级请求也要点击同意。
2.修复两个obsolete错误,会有相关提示。
3.Lua->Gen Lua Wrap File生成Wrap文件。(此类脚本是对Unity中常用组件的二次包装,Lua运行后,会把Wrap文件加载到Lua运行环境中。使得Lua调用Wrap文件,Wrap调用C#,间接地实现Lua调用C#。Wrap文件可以提高lua的执行效率。其位置为uLua\Source\Lua\Wrap)
4.Game->Build X Resource。生成的AssetBundle文件会放在StreamingAsset文件夹下,生成的过程中还会把Lua文件夹下的所有脚本复制到该目录。
5.ULua与C#交互:
a:
C#代码中执行Lua代码:
LuaState lua = new LuaState();
lua.DoString(“print(‘Goodbye’)”);
<1>在C#中引入LuaInterface;
Lua中操作Unity的类:
luanet.load_assembly(‘UnityEngine’)
GameObject = luanet.import_type(‘UnityEngine.GameObject’)
BoxCollider = luanet.import_type(‘UnityEngine.BoxCollider’)
local player = GameObject(‘King’)
player:AddComponent(luanet.ctype(BoxCollider))
<1>luanet已经被封装到LuaInterface命名空间内,在Lua代码中可以直接使用此对象
<2>Lua中操作C#的类创建对象,不写new
<3>Lua中C#的类所创建的对象,访问对象中的方法要用冒号
b:
Lua代码中操作Unity内的类(wrap方式):
luanet.load_assembly(‘UnityEngine’)
GameObject = UnityEngine.GameObject
BoxCollider = UnityEngine.BoxCollider
local player = GameObject(‘King’)
player:AddComponent(BoxCollider.GetClassType())
C#中:
LuaScriptMgr lua = new LuaScriptMgr();
lua.Start();
<1>要把AppConst.cs中的DebugMode修改为true
<2>使用Wrap方式时,运行Lua代码用的是LuaScriptMgr。用这种方式实现Lua调用C#,依赖的是之前生成的LuaWrap文件。因此,当我们要操作的脚本没有生成XXXWrap脚本时,如果我们如此操作:打开uLua\Editor\WrapFile.cs->添加_GT(typeof(类名)) ->Clear LuaBinder File + Wrap File -> Gen Lua Wrap Files
6.正式项目开发时,Appconst.cs中的ExampleMode修改为false,也就可以把Example文件夹删除掉了。DebugMode = false, UpdateMode = true, AppName = “项目名称”。webUrl要与服务器端ip地址保持一直。
7.设置预制体的AssetLabels信息,后缀设置为assetbundle。在Packager.cs脚本中对于Appconst.ExampleMode为假的情况下进行处理,让脚本可以打包所有指定了AssetBundle信息的物体。(在打包资源的时候如果出现了LuaWrap文件夹下的脚本错误,先清空LuaWrap文件,生成AB资源,再生成LuaWrap文件)
8.从服务器端下载资源
<1>Web网站方式,前面已经介绍过了
<2>Socket方式:
VS打开Service\HttpServer.cs,配置15行中的host为服务器的ip,28行为服务器给客户端资源的存放地址。点击生成->生成解决方案。
9.场景中创建一个空物体,挂载”GlobalGenerator.cs”脚本,作为框架的入口。
10.打包项目后,修改lua脚本,重新生成AB资源,就可以完成热更新啦!
②XLua
1.将XLua中的Plugins和XLua文件夹拷贝到该项目中
2.C#调用Lua
<1>using XLua;
<2>创建运行Lua代码的虚拟机(出于开销考虑,建议只创建一个)
LuaEnv luaEnv = new LuaEnv();
luaEnv.DoString(“print(‘mkcode’)”);
3.调用外部Lua文件
<1>在Resources文件夹下创建后缀为txt的lua文件。eg:fileName.lua.txt
<2>luaEnv.DoString(“require ‘fileName’”);
<3>C#获取Lua数据
luaEnv.Global.Get(“a”);
luaEnv.Global.Get(“b”);
4.Lua调用C#
需要在C#的命名空间前加上”CS.”
获取C#中的类:CS.UnityEngine.GameObject
获取C#中的方法:CS.UnityEngine.GameObject.Find()
获取C#的字段:若是public,可直接用self.字段名访问;若为private,可用代码获取访问权xlua.private_accessible(CS.类名)
5.环境初始化:
a.File->Build Settings->Player Settings->Configuration
修改Scripting Define Symbols: HOTFIX_ENABLE
b.XLua->Generate Code
生成Wrap文件,存放在XLua/Gen处
c.XLua->Hotfix Injcet In Editor
如果出现”please install the Tools”的error,需要把Tools文件夹拷贝到与Asset同级的位置。每次修改完C#文件都要重新注入一次。
6.HotFix特性标签
a.在开发阶段时,以后可能需要热补丁修复的类要在其头部添加[HotFix],同时using Xlua;
b.lua代码中的HotFix语法:
xlua.hotfix(CS.className, ‘functionName’, luaFucntion)
eg1:
xlua.hotfix(CS.Test, ‘Hello’, function()
print(‘Lua Goodbye~’)
end)
eg2.
xlua.hotfix(CS.Test, ‘Add’, function(self, a, b)
print(a + b)
end)
注:有参方法需要传递当前脚本对象,即此处的self
7.在一个启动场景中创立一个空物体HotFixManager,同时挂载同名脚本,脚本内定义LuaEnv虚拟机,用于热更新。至于HotFixManager的编写,就不再此处详述了。
8.创建StreamingAssets文件夹,使用WWW类加载该文件夹下的资源。
总算是大体整理完成了,可能在某些方面还会有些小错误,若是发现再改正,还需要继续学习lua。不过这一阶段结束之后就可以转入其他课程了~