1,首先将这个四个文件(夹)放入工程中
2,设置宏:HOTFIX_ENABLE
3,在Editor模式下,如果测试热更新代码,需要首先生成代码 XLua-Generate Code 再注入代码 Hotfix Inject In Editor 并且需要将Xlua工程中的Tools文件夹也放入到当前工程中 参考官方案例8
4,有可能出现.如果在注入时出现警告而没有出现注入成功, 如: WARNING:Theruntime version supported by this application is unavailable. Using default runtime : v4.0.30319需要引入三个dll路径如下 或者是否是中文路径
EditorDataManagedUnity.Cecil.Pdb.dll + Unity.Cecil.Mdb.dll + Unity.Cecil.dll
5.被Xlua调用(更新)的方法需要添加[LuaCallCSharp]标签
6.在发布时如果报错,需要将Xlua案例删除掉 再清空注入代码重新生成.
7.
开发过程:
首先开发业务代码->在所有可能出现问题的类上打上hotfix的标签,在所有lua调用CSharp的方法上打上LuaCallCSharp,在所有CSharp调用Lua的方法上打上CSharpCallLua->打包发布->修改bug时只需要更新Lua文件,修改资源时(声音,模型,贴图,图片,UI)只需要更新ab包。用户只需要去下载lua文件跟ab包。
8.记得打标签!!!!! 和修改Lua脚本为UTF-8
9.在C#中和Xlua交互
LuaEnv luaEnv;
void Start()
{
luaEnv = new LuaEnv();
luaEnv.AddLoader(MyLoader);
luaEnv.DoString("require 'fish'");
}
private byte[] MyLoader(ref string fileName)
{
string absPath = @"F:BaiduNetdiskDownloadXluaProjectsluascripts" + fileName + ".lua.txt";
return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));
}
在Lua中与C#交互(进行更新)
xlua.hotfix(CS.Treasour,'CreatePrize',function(self)
(类,方法,function(self))
在C#中最后销毁物体时将虚拟机关闭 在OnDistroy中 调用luaEnv.Dispose();
10.
调用LuaEnv.Dispose时,报“try to dispose a LuaEnv with C# callback!”错是什么原因?
如果是通过xlua.hotfix(class, method, func)注入到C#,则通过xlua.hotfix(class, method, nil)删除委托(这个lua脚本需要在销毁之前调用可以在OnDisable()中);
11.在lua中调用任何Unity中的API需要先找到类,再 类.方法 调用当前类中的公有方法或字段要使用self+.来调用字段, self+:来调用方法,如果是类中组件的实例或者Unity的非静态API, 如AudioSource的实例as 那么也需要self.as:Play() 注意是冒号,静态UnityAPI可以直接类名点调用
lua如果需要访问一个C#类中的私有属性或方法 需要添加xlua.private_accessible(CS.Gun) 括号中是类名,其他固定写法
12. luaenv最好保证一个项目全局只有一个实例.并且这个实例应该在Awake()方法中进行初始化
13.如果只是对一个字段进行操作. 可以不对类中任何方法(即使有引用过这个字段的地方)添加[luacallcsharp]标签,前提考虑是否有后续方法将字段修改了,比如在Start中对一个字段进行初始化, 那么没必要对这个Start方法添加luacallcsharp标签.
14.如果想要对一个方法保留之前的代码运行再添加一些功能可以在lua中引入一个文件, 使用 local util = require 'util' 设置一个本地变量方便使用这个文件,这个文件在Xlua中,可以进行搜索复制到与当前和C#交互的lua脚本同级目录下, 在lua中将xlua.hotfix替换成util.hotfix参数相同, 这样就可以在lua方法中先调用一下要修改的方法再去执行更新的罗技,呸! 逻辑.
15.在lua中是不支持float类型与类型转换的,所以当使用Mathf.Clamp.Range(float,float)Mathf.Clamp.Range(int,int) 类似这种lua没法区分的重载方法 需要在C#中去处理, 可以自己写一个静态函数再通过lua调用, 如果是这个问题也可以通过调用Mathf.Floor 来向下取整
16.xlua不支持泛型, 所以使用GetComponent时可以这样用: GetComponent('Rigidbody')
17.非Unity API 不用使用UnityEngine.xxx 需要使用CS.XXX, 但是使用也不会报错
18.
AssetBundle ab = AssetBundle.LoadFromFile(@"F:BaiduNetdiskDownloadXluaProjectsFishingJoyAssetsBundle"+filePath);
GameObject gameObject = ab.LoadAsset<GameObject>(resName); 类似这种ab包加载的时候, 因为lua中是没有泛型的, 所以当使用lua去更新游戏资源的时候应该提前将静态方法在C#中进行实现, 这样就可以在lua中调用了
19.由于在工程发布后没办法添加新类, 如果在更新逻辑时需要添加一些类挂到某些gameObject上的时候 可以提前写一些接口和方法, 但是工作量太大, 不如提前创建几个空脚本 当需要的时候通过lua添加到游戏物体上就好了
20.如果希望调用一个资源的实例方法, 这个脚本所在的物体又是动态添加的, 所以在lua那边没办法拿到实例:function, 可以通过提前在可以拿到的实例上添加这个动态添加的物体的引用.