找回密码
 立即注册
查看: 305|回复: 0

Unity XLua热更新

[复制链接]
发表于 2021-8-13 12:20 | 显示全部楼层 |阅读模式
持续更新
文章目录

    相关链接基础案例关于XLua的生成代码和代码注入简单热更新使用Lua脚本文件


相关链接

    ? xlua迁入项目Lua菜鸟教程Lua常用函数Lua 封装自己的库Lua元表Lua类实现xlua官方教程xlua官方问答比较好的B站项目教程

基础案例

0基础的先看 xlua迁入项目
  1. /*
  2. *  Author : Jk_Chen
  3. */using System.Collections;using System.Collections.Generic;using UnityEngine;using XLua;/// <summary>/// 热更新类,进行代码的修复/// </summary>publicclassXLuaFix:MonoBehaviour{staticLuaEnv lua;staticint tmp =2;voidAwake(){
  4.         lua =newLuaEnv();// 简单执行Lua语句
  5.         lua.DoString("print 'lua print'");// 调用C#类的公有静态方法
  6.         lua.DoString("CS.UnityEngine.Debug.Log('cs debug')");
  7.         lua.DoString("CS.XLuaFix.Print()");// 先让某个类的私有成员可访问,再调用私有静态方法
  8.         lua.DoString("xlua.private_accessible(CS.XLuaFix)");
  9.         lua.DoString("CS.XLuaFix.PrivatePrint()");// 修改静态变量
  10.         lua.DoString("CS.XLuaFix.tmp=3");
  11.         lua.DoString("print('修改后的静态变量为:' .. CS.XLuaFix.tmp)");}publicstaticvoidPrint(){
  12.         Debug.Log("public static");}privatestaticvoidPrivatePrint(){
  13.         Debug.Log("private static");}privatevoidOnDestroy(){
  14.         lua.Dispose();}}
复制代码


关于XLua的生成代码和代码注入

代码需要进行热更新的时候,需要进行生成代码和代码注入。
请在每次修改代码后(运行前)都执行一遍该操作。
代码注入后Debug会比较麻烦,因为Log内寻找不到是哪行代码的运行结果。
看得到,但是不能通过点击直接找到哪行


原来是这样的



如果不需要热更新可以把生成的代码Clear掉
简单热更新

必要步骤
    需要热更新的类前加[Hotfix]运行前生成代码和代码注入
  1. /*
  2. *  Author : Jk_Chen
  3. */using System.Collections;using System.Collections.Generic;using UnityEngine;using XLua;/// <summary>/// 热更新类,进行代码的修复/// </summary>[Hotfix]publicclassXLuaFix:MonoBehaviour{staticLuaEnv lua;publicstaticint tmp =2;voidAwake(){
  4.         lua =newLuaEnv();// 调用带参函数
  5.         lua.DoString("CS.XLuaFix.Print(CS.XLuaFix.tmp)");// 修改函数
  6.         lua.DoString(@"xlua.hotfix(CS.XLuaFix,'Print',function(value)
  7.                 CS.UnityEngine.Debug.Log('After ' .. value*value)
  8.             end)");// 调用修改后的函数
  9.         lua.DoString("CS.XLuaFix.Print(CS.XLuaFix.tmp)");}publicstaticvoidPrint(intvalue){
  10.         Debug.Log("Defore "+value);}privatevoidOnDestroy(){
  11.         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之前完成。
所以我们在释放虚拟机之前释放这些委托即可:
  1. privatevoidOnDestroy(){// 释放委托
  2.         lua.DoString(@"xlua.hotfix(CS.XLuaFix,'Print',nil)");
  3.         lua.Dispose();}
复制代码
使用Lua脚本文件

之前使用到的都是在C#代码内使用DoString来调用Lua,这样有一个很麻烦的地方就是,由于每次都会修改代码,所以都需要生成和注入。而且和我们的热更新也不搭嘎。
所以我们现在使用脚本文件的方式。require函数可以加载一个lua脚本,但如果lua脚本不在Resources路径下,或者不在默认的目录下,此时是加载不到对应的lua脚本的。
我们需要自己写一个loader来适配lua脚本的位置:
c#代码:
  1. /*
  2. *  Author : Jk_Chen
  3. */using System.Collections;using System.Collections.Generic;using UnityEngine;using XLua;/// <summary>/// 热更新类,进行代码的修复/// </summary>[Hotfix]publicclassXLuaFix:MonoBehaviour{staticLuaEnv lua;publicstaticint tmp =2;voidAwake(){
  4.         lua =newLuaEnv();// 定义loader,从Assets/Lua目录下读取,已自带.lua.txt// 例如读取Assets/Lua/xx.lua.txt只需要 lua.DoString("require('xx')");
  5.         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;}});
  6.         lua.DoString("require('XLuaFix')");}publicstaticvoidPrint(intvalue){
  7.         Debug.Log("Defore "+value);}privatevoidOnDestroy(){// 释放委托
  8.         lua.DoString("require('XLuaFixDispose')");// 释放虚拟机
  9.         lua.Dispose();}}
复制代码
lua脚本: XLuaFix.lua.txt
  1. -- 调用带参函数
  2. CS.XLuaFix.Print(CS.XLuaFix.tmp)-- 修改函数
  3. xlua.hotfix(CS.XLuaFix,'Print',function(value)
  4.         CS.UnityEngine.Debug.Log('After '.. value*value)end)-- 调用修改后的函数
  5. CS.XLuaFix.Print(CS.XLuaFix.tmp)
复制代码
lua脚本: XLuaFixDispose.lua.txt
  1. -- 释放委托
  2. xlua.hotfix(CS.XLuaFix,'Print',nil)
复制代码
本人是用notepad写lua脚本的,好处就是当我只需要写lua时我就不需要等十几秒打开VS,notepad足够轻量


notepad配置博客

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 09:31 , Processed in 0.090043 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表