|
持续更新
文章目录
相关链接基础案例关于XLua的生成代码和代码注入简单热更新使用Lua脚本文件
相关链接
? xlua迁入项目Lua菜鸟教程Lua常用函数Lua 封装自己的库Lua元表Lua类实现xlua官方教程xlua官方问答比较好的B站项目教程
基础案例
0基础的先看 xlua迁入项目- /*
- * Author : Jk_Chen
- */using System.Collections;using System.Collections.Generic;using UnityEngine;using XLua;/// <summary>/// 热更新类,进行代码的修复/// </summary>publicclassXLuaFix:MonoBehaviour{staticLuaEnv lua;staticint tmp =2;voidAwake(){
- lua =newLuaEnv();// 简单执行Lua语句
- lua.DoString("print 'lua print'");// 调用C#类的公有静态方法
- lua.DoString("CS.UnityEngine.Debug.Log('cs debug')");
- lua.DoString("CS.XLuaFix.Print()");// 先让某个类的私有成员可访问,再调用私有静态方法
- lua.DoString("xlua.private_accessible(CS.XLuaFix)");
- lua.DoString("CS.XLuaFix.PrivatePrint()");// 修改静态变量
- lua.DoString("CS.XLuaFix.tmp=3");
- lua.DoString("print('修改后的静态变量为:' .. CS.XLuaFix.tmp)");}publicstaticvoidPrint(){
- Debug.Log("public static");}privatestaticvoidPrivatePrint(){
- Debug.Log("private static");}privatevoidOnDestroy(){
- lua.Dispose();}}
复制代码
关于XLua的生成代码和代码注入
代码需要进行热更新的时候,需要进行生成代码和代码注入。
请在每次修改代码后(运行前)都执行一遍该操作。
代码注入后Debug会比较麻烦,因为Log内寻找不到是哪行代码的运行结果。
看得到,但是不能通过点击直接找到哪行
原来是这样的
如果不需要热更新可以把生成的代码Clear掉
简单热更新
必要步骤
需要热更新的类前加[Hotfix]运行前生成代码和代码注入
- /*
- * Author : Jk_Chen
- */using System.Collections;using System.Collections.Generic;using UnityEngine;using XLua;/// <summary>/// 热更新类,进行代码的修复/// </summary>[Hotfix]publicclassXLuaFix:MonoBehaviour{staticLuaEnv lua;publicstaticint tmp =2;voidAwake(){
- lua =newLuaEnv();// 调用带参函数
- lua.DoString("CS.XLuaFix.Print(CS.XLuaFix.tmp)");// 修改函数
- lua.DoString(@"xlua.hotfix(CS.XLuaFix,'Print',function(value)
- CS.UnityEngine.Debug.Log('After ' .. value*value)
- end)");// 调用修改后的函数
- lua.DoString("CS.XLuaFix.Print(CS.XLuaFix.tmp)");}publicstaticvoidPrint(intvalue){
- Debug.Log("Defore "+value);}privatevoidOnDestroy(){
- lua.Dispose();}}
复制代码
代码修复成功,但是报错了。这个错误官方有回答:
这是由于C#还存在指向lua虚拟机里头某个函数的delegate,为了防止业务在虚拟机释放后调用这些无效(因为其引用的lua函数所在虚拟机都释放了)delegate导致的异常甚至崩溃,做了这个检查。
怎么解决?释放这些delegate即可,所谓释放,在C#中,就是没有引用:
你是在C#通过LuaTable.Get获取并保存到对象成员,赋值该成员为null;
你是在lua那把lua函数注册到一些事件事件回调,反注册这些回调;
如果你是通过xlua.hotfix(class, method, func)注入到C#,则通过xlua.hotfix(class, method, nil)删除;
要注意以上操作在Dispose之前完成。
所以我们在释放虚拟机之前释放这些委托即可:- privatevoidOnDestroy(){// 释放委托
- lua.DoString(@"xlua.hotfix(CS.XLuaFix,'Print',nil)");
- lua.Dispose();}
复制代码 使用Lua脚本文件
之前使用到的都是在C#代码内使用DoString来调用Lua,这样有一个很麻烦的地方就是,由于每次都会修改代码,所以都需要生成和注入。而且和我们的热更新也不搭嘎。
所以我们现在使用脚本文件的方式。require函数可以加载一个lua脚本,但如果lua脚本不在Resources路径下,或者不在默认的目录下,此时是加载不到对应的lua脚本的。
我们需要自己写一个loader来适配lua脚本的位置:
c#代码:- /*
- * Author : Jk_Chen
- */using System.Collections;using System.Collections.Generic;using UnityEngine;using XLua;/// <summary>/// 热更新类,进行代码的修复/// </summary>[Hotfix]publicclassXLuaFix:MonoBehaviour{staticLuaEnv lua;publicstaticint tmp =2;voidAwake(){
- lua =newLuaEnv();// 定义loader,从Assets/Lua目录下读取,已自带.lua.txt// 例如读取Assets/Lua/xx.lua.txt只需要 lua.DoString("require('xx')");
- lua.AddLoader((refstring file)=>{string path = System.IO.Path.Combine("Assets/Lua", file +".lua.txt");if(System.IO.File.Exists(path)){return System.IO.File.ReadAllBytes(path);}else{returnnull;}});
- lua.DoString("require('XLuaFix')");}publicstaticvoidPrint(intvalue){
- Debug.Log("Defore "+value);}privatevoidOnDestroy(){// 释放委托
- lua.DoString("require('XLuaFixDispose')");// 释放虚拟机
- lua.Dispose();}}
复制代码 lua脚本: XLuaFix.lua.txt- -- 调用带参函数
- CS.XLuaFix.Print(CS.XLuaFix.tmp)-- 修改函数
- xlua.hotfix(CS.XLuaFix,'Print',function(value)
- CS.UnityEngine.Debug.Log('After '.. value*value)end)-- 调用修改后的函数
- CS.XLuaFix.Print(CS.XLuaFix.tmp)
复制代码 lua脚本: XLuaFixDispose.lua.txt- -- 释放委托
- xlua.hotfix(CS.XLuaFix,'Print',nil)
复制代码本人是用notepad写lua脚本的,好处就是当我只需要写lua时我就不需要等十几秒打开VS,notepad足够轻量
notepad配置博客
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|