Xlua官方开源地址:

https://github.com/Tencent/xlua

首先先说明下,因为我们的项目是比较旧的项目,所以当时并未使用任何热更技术,所有的代码都是用c#写的,导致到项目后期才忽然想使用热更就非常困难了。当时研究了不少热更框架发现大部分都无法再弥补过去的疏忽,直到出现了Xlua,作者宣称项目可以继续由C#编写,只有在热更修复的时候才是用lua,我觉得有戏就研究了下。

根据方法一提示,要使用Xlua就要在每个类里头打上[Hotfix]标签,刚开始的想法是通过写一个工具遍历所有脚本,通过正则表达式匹配然后再在所有类中打上[Hotfix]标签,直到又仔细品味了下方法二,在一个static类的static字段或者属性里头配置一个列表,就可以通过白名单方式实现配置。

1.我们先从github中下载xula框架,仅仅解压缩Asset和Tools,放到我们Unity项目的根目录下

我们新建一个LuaManager脚本作为Lua虚拟机的管理组件,具体代码如下:

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;public class LuaManager : MonoBehaviour {public static LuaManager _instance;public static LuaManager Instance{get{return _instance;}}[CSharpCallLua]public delegate void LuaDelegate(string paras);/// <summary>/// 定义一个Delegate,Lua结果将传参回调给该Delegate/// </summary>public static LuaDelegate LuaFunc;/// <summary>/// 定义一个Lua虚拟机,建议全局唯一/// </summary>public static LuaEnv luaEnv;void Awake(){_instance = this;}public void LuaEnvInit(){luaEnv = new LuaEnv();luaEnv.AddLoader(MyLoader);///lua脚本的主入口luaEnv.DoString(@"require 'main'");//获取Lua中全局function,然后映射到delegateluaEnv.Global.Get("LuaFunc", out LuaFunc);}/// <summary>/// 编写一个Loader,当一个文件被require时,这个loader会被回调,其参数是调用require所使用的参数,如果该loader找到文件,可以将其读进内存/// </summary>/// <param name="filePath"></param>/// <returns></returns>private byte[] MyLoader(ref string filePath){string absPath = Path.Combine(Application.dataPath, "../LuaScripts/" + filePath + ".lua");return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));}}

同时在项目根目录新建一个LuaScripts文件夹,在文件夹中新建一个main.lua文件,注意用UTF8编码,若使用其他编码可能会出错,这是lua脚本的主入口,编写mian.lua脚本:

function LuaFunc(path)print("do lua function!")require(path)
end

然后最重要的一步来了,创建一个Editor文件夹,若不在Editor文件夹中创建会报错,然后在该目录下创建HotficCfg脚本,编写热丁配置文件:

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using UnityEngine;
using XLua;public static class HotfixCfg
{[Hotfix]public static List<Type> by_property{get{//从程序集中获取全部类信息var allTypes = Assembly.Load("Assembly-CSharp").GetTypes();var nameSpace = new List<string>();//遍历所有类筛选符合规则的命名空间foreach (var t in allTypes){if (t.Namespace != null && (t.Namespace.StartsWith("MyGame", StringComparison.CurrentCulture))){if (!nameSpace.Contains(t.Namespace)){nameSpace.Add(t.Namespace);}}}var retList = new List<Type>();var sb = new StringBuilder();//遍历所有类筛选所有包含该命名空间的Type对象foreach (var t in allTypes){if (nameSpace.Contains(t.Namespace)){retList.Add(t);sb.AppendLine(t.FullName);}}//输出所有Type信息到项目根目录HotTypes.txt文本中File.WriteAllText(Path.Combine(Application.dataPath, "../HotTypes.txt"), sb.ToString());return retList;}}
}

同时创建测试脚本TestScript.Cs以及在LuaScripts目录下创建lua热补丁脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;namespace MyGame
{public class TestScript : MonoBehaviour{public string fileName = "test";//这里是引用的lua文件名void Start(){LuaManager.Instance.LuaEnvInit();}void Update(){Debug.Log("Hello World!");}public void DoLuaFunc(){LuaManager.LuaFunc(fileName);}}
}

Lua热补丁脚本

--Cs.MyGame.TestScript,脚本类名,要求CS.命名空间.类名
--Update,为要替换的方法
--function ( self ),默认写法,self类似C#中的this,
--若有要使用该类中对象的公共方法可用self.定义的对象名:Function(),
--例如:self.gameObject.SetActive(true)等价于this.gameObject.SetActive(true)
--若是静态方法可直接使用".",但必须引入完整命名空间,例如CS.UnityEngine.Debug.Log()xlua.hotfix(Cs.MyGame.TestScript, 'Update', function ( self )
print("Hello Lua!")
end)

然后在Build Settings->Player Settings中添加宏HOTFIX_ENABLE,等待编译结束Xlua页签中会多一个Hotfix Inject In Editor选项,此时选择Generate Code,等待Log中提示finished就完成了,再选择Hotfix Inject In Editor,等待提示inject finish就结束了。注意:每次编译时要等待右下角转菊花结束,不然可能会出错,此时可选Clear Generated Code,然后重复以上步骤。

然后我们创建个按钮运行测试下

刚开始Update中一直在Debug"Hello World"字符串,当我们执行DoluaFunc函数以后,Update中的代码被test.lua中的代码替换了,到此我们热更新实验就成功了。

那么如果项目并非是用命名空间的呢,能否热更呢?当然是可以的,以下为按照目录设定热更标签的代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using XLua;public static class HotfixCfg
{[Hotfix]public static List<Type> by_property{get{var allTypes = Assembly.Load("Assembly-CSharp").GetTypes();//获取类名的正则表达式var pattern = @"class\s+(\w+)";var reg = new Regex(pattern);//设置要打标签脚本的根路径var dir = Application.dataPath + "/Scripts";var dirInfo = new DirectoryInfo(dir);var allCS = dirInfo.GetFiles("*.cs", SearchOption.AllDirectories);var allFiles = new List<FileInfo>();allFiles.AddRange(allCS);var fileTypes = new HashSet<string>();foreach (var f in allFiles){var lines = File.ReadAllLines(f.FullName);foreach (var l in lines){var matchs = reg.Matches(l);if (matchs.Count > 0){var className = matchs[0].Groups[1].ToString();if (!fileTypes.Contains(className))fileTypes.Add(className);}}}var retList = new List<Type>();var sb = new StringBuilder();foreach (var t in allTypes){if (fileTypes.Contains(t.Name)){retList.Add(t);sb.AppendLine(t.FullName);}}File.WriteAllText(Path.Combine(Application.dataPath, "../HotTypes.txt"), sb.ToString());return retList;}}
}

然后我们把TestScript的命名空间去掉,修改test.lua文件,去掉命名空间

xlua.hotfix(CS.TestScript, 'Update', function ( self )
print("Hello Lua!")
end)

最后测试也是成功的

Unity热更之旧项目救星——Xlua热补丁修复相关推荐

  1. unity热更- 2 游戏大版本更新和热更新

    游戏上线后,遇见bug或者需要更新内容(包括资源,玩法,数值调整,游戏脚本等)的时候,一般有2种做法.第一种,发个新包,然后让玩家下载新的版本:第二种,在游戏内更新,游戏启动时去下载需要更新的资源.第 ...

  2. 视频教程-热更新框架设计之热更流程与热补丁视频课程-Unity3D

    热更新框架设计之热更流程与热补丁视频课程 二十多年的软件开发与教学经验IT技术布道者,资深软件工程师.具备深厚编程语言经验,在国内上市企业做项目经理.研发经理,熟悉企业大型软件运作管理过程.软件架构设 ...

  3. Unity3D热更设计:一款基于 HybridCLR的C#热更方案

    在这篇文章之前,可以转到我的这两篇博客:C#热更方案 HybridCLR尝鲜:Windows及Android打包.超详细的Unity3D热更新框架,附示例链接,小白也能看的懂_鹿野素材屋的博客-CSD ...

  4. 【UGF】GameFramework接入HybridCLR(wolong)卧龙C#热更框架

    HybridCLR的推广已经做得相当好了,而且热更领域突然杀出一匹黑马,热度很高,不再多做介绍,可以点击进入HybridCLR开源地址了解详情. 在此之前用过tolua和xlua热更框架, 因为C#开 ...

  5. Unity 游戏用XLua的HotFix实现热更原理揭秘

    本文通过对XLua的HoxFix使用原理的研究揭示出来这样的一套方法.这个方法的第一步:通过对C#的类与函数设置Hotfix标签.来标识需要支持热更的类和函数.第二步:生成函数连接器来连接LUA脚本与 ...

  6. Java和U3D比较,Unity热更方案 ILRuntime 和 toLua的比较

    前言 目前市面上流行的热更方案就是lua系列和ILRuntime,选取哪一种需要根据自己的项目进行比对. 无论是ILRuntime还是toLua都是市面上有在用到的热更方案.直观上来讲,都可以通过把代 ...

  7. unity 代码热更+资源管理框架总结

    游戏要做热更涉及到什么方面呢 首先就是代码热更,然后就是资源热更 这些热更新都依赖于打AssetBundle 然而打AssetBundle 你还要上传服务器-对比更新-客户端下载-加载-卸载这些流程 ...

  8. unity python做热更_[专栏作家]基于ILRuntime的完整C#热更方案

    原标题:[专栏作家]基于ILRuntime的完整C#热更方案 好久不见.最近一段时间公司二次创业,实在是忙的脚打后脑勺,有段时间没来跟大家分享心得了,昨天终于有了一个初步的完结,也终于有时间和精力跟大 ...

  9. Unity中的热更新的基础知识,Xlua与ILRuntime基础知识

    1.什么是热更新 热更新是指在不需要重新编译打包游戏的情况下,在线更新游戏中的一些非核心代码和资源,比如活动运营和打补丁.热更新分为资源热更新和代码热更新两种,代码热更新实际上也是把代码当成资源的一种 ...

  10. unity menuitem_Unity热更_打AssetBundles包

    Unity热更_打AssetBundles包 Unity开发离不了热更新,现在市面上有很多的热更方案,XLua.ToLua以及C#热更方案ILRuntime,以腾讯的XLua为例,若要实现热更新,As ...

最新文章

  1. Python Qt GUI设计:QComboBox下拉列表框类(基础篇—14)
  2. 倒排索引PForDelta压缩算法——基本假设和霍夫曼压缩同
  3. JSP、EL和JSTL-学习笔记03【EL介绍和运算符、EL获取域中存储的数据】
  4. Android-无线连接设备调试
  5. 让孩子尽快了解这个世界
  6. 《Programming WPF》翻译 第9章 6.我们进行到哪里了?
  7. c语言 自动化编译环境,《C编程.开始C》3.编译基础
  8. go语言 mysql卡死_一次mysql死锁的排查过程-Go语言中文社区
  9. SpringMVC学习--springmvc原理
  10. WebbUpload上传组件(cnblog 一位网友写的)
  11. i5 9400f和GTX1660能玩战地5吗?
  12. win11为何七代酷睿无法升级 Windows11七代酷睿无法升级的解答
  13. 陈皓:不灌鸡汤,说真的年龄渐长,技术人的发展之路该怎么走?
  14. java设置http超时时间_Java设置Http请求超时时间
  15. Python基础课程笔记·嵩天
  16. CNtV电视直播解析PHP,电视直播
  17. RSS阅读器FeedDemon使用方法
  18. matlab scatter3点颜色,使用for循环MATLAB时,scatter3中的系列颜色与Legend不匹配
  19. Learning to Rank(LTR)(转)
  20. Android Snackbar使用方法及小技巧-design

热门文章

  1. android webview 清空内容,Android WebView清空缓存
  2. AWS云上混沌工程实践之启动篇
  3. CUDA各版本官方下载地址
  4. boost LNK2005 重定义错误
  5. 立方单位换算计算机,体积单位换算
  6. hash函数(哈希表)
  7. 洛谷试炼场 计数问题
  8. Project 制作工作进度计划 排除休息日
  9. 史上最全后端技术介绍
  10. 遗传算法解决车辆调度问题