一、环境配置

要实现热更新功能,我们首先需要开启热更新的宏。操作方法是在「File->Build Settings->Player Settings->Player->Other Settings->Scripting Define Symbols」选项中添加HOTFIX_ENABLE

开启后,在xLua的菜单中就出现了「Hotfix Inject In Editor」选项。

当我们在开发补丁版本需要进行热更新测试时,都需要点击一次上图中的「Generate Code」选项重新生成一次代码,然后再点击「Hotfix Inject In Editor」进行注入。
如果注入时出现了如下错误信息,我们需要将xLua源码中的「Tools」文件夹复制到我们工程的根目录下。

以上两步操作如果成功的话,在控制台都会有相应提示。环境配置完成后,可以运行xLua自带的热更新示例,测试一下是否能热更成功。

二、热更新原理

首先引用一段xLua作者的话,介绍一下xLua实现热更新的原理(原文出处)


热补丁的基本原理其实非常简单,了解后任何程序员都很容易分析出开销,比如对于这个类

public class Calc
{int Add(int a, int b){return a + b}
}

打了hotfix标签后,xLua会在il层面注入代码,注入之后这个类会类似这样:

public class Calc
{static Func<object, int, int, int> hotfix_Add = null;int Add(int a, int b){if (hotfix_Add != null) return hotfix_Add(this, a, b);return a + b}
}

如果lua中执行了hotfix调用,hotfix_Add会指向一个lua的适配函数。


也就是说,在给类加上[Hotfix]特性后,我们就可以在Lua中指定需要“替换”的方法。然后xLua就会将委托指向Lua中对应的函数。

明白了原理后,我们来尝试实现一个简单的案例

比如原本有一个C#脚本如下所示

[Hotfix]
public class HotfixExample : MonoBehaviour
{private float _timer = 0f;[LuaCallCSharp]private void Update(){_timer += Time.deltaTime;if (_timer > 2f){_timer = 0;Debug.Log("这是C#代码");}}
}

运行结果如下

现在我们希望通过热更新的方式修改Update方法,那么只需要在Lua脚本中调用xlua.hotfix()方法即可。该方法的第一个参数传入需要热更的C#类,第二个参数传入需要覆盖的方法名,第三个参数传递一个function,作为覆盖后的新方法。

-- HotfixExample.lua.txt
local class = CS.XLuaExample.HotfixExample
local engine = CS.UnityEngine
-- 允许访问私有成员
xlua.private_accessible(class)
xlua.hotfix(class,"Update",function(self)self._timer=self._timer + engine.Time.deltaTimeif self._timer>2 thenself._timer = 0engine.Debug.Log("这是Lua代码")end
end)

在运行结束前还需要将注入到C#方法的引用置空,所以再写一个置空的Lua脚本

-- HotfixExampleDispose.lua.txt
xlua.hotfix(CS.XLuaExample.HotfixExample,"Update",nil)

然后再写个C#脚本模拟调用Lua脚本的入口

public class StartLua:MonoBehaviour
{private LuaEnv _luaEnv;private void Awake(){_luaEnv = new LuaEnv();_luaEnv.DoString("require 'HotfixExample'");}private void OnDisable(){_luaEnv.DoString("require 'HotfixExampleDispose'");}private void OnDestroy(){_luaEnv.Dispose();}
}

重新生成并注入代码后,运行项目,就会发现热更的Lua代码已经生效了

当然,在某些情况下我们只需要在原方法的基础上增加一点逻辑,而不是将方法完全覆盖。这时我们可以引入xLua中的util.lua脚本,并使用其提供的hotfix_ex()方法,实现增量热更

local class = CS.XLuaExample.HotfixExample
local engine = CS.UnityEngine
xlua.private_accessible(class)local util = require 'util'
util.hotfix_ex(class,"Update",function(self)-- 调用原本的方法self.Update(self)if self._timer>1 thenengine.Debug.Log("这是Lua代码")end
end)

效果如下

下面来总结一下热更新的流程

  • 首先我们在开发时应该在所有可能需要热更的类前加上[Hotfix]特性,在所有可能需要调用Lua脚本的地方加上[CSharpCallLua],在所有可能被Lua调用的地方加上[LuaCallCSharp],也可以通过反射实现。
  • 如果真的需要热更新,那就通过编写Lua脚本覆盖所需的方法。Lua脚本应该有一个统一的入口集中加载。
  • 最后将热更新的脚本、资源上传到服务器。玩家的客户端检查到更新后将热更新内容下载到本地,完成热更新。

xLua热更新(二)实现热更新相关推荐

  1. Lua快速入门篇(XLua教程)(Yanlz+热更新+xLua+配置+热补丁+第三方库+API+二次开发+常见问题+示例参考)

                            <Lua热更新> ##<Lua热更新>发布说明: ++++"Lua热更新"开始了,立钻哥哥终于开始此部分的探 ...

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

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

  3. native react 更新机制_react-native热更新全方位讲解

    最近在研究热更新技术,看了网上各个大佬的博客,整体流程上总是卡壳.跳了几天坑,刚刚终于把简单的热更新流程跑通,现在也正在一边学习更新,一边整理资料,在此篇博客上记录操作流程,希望我的实践能帮助各位同行 ...

  4. uniapp 热更新和整包更新

    uniapp 热更新和整包更新 版本校验接口返回 自动更新 自动下载APK并安装 弹出下载APK手动安装 参考资料 版本校验接口返回 https://192.168.1.113/public/mobi ...

  5. 【热更新】游戏热更新方案

    游戏热更新方案 热更新演化 热更新方案 [1] 进程切换 1.1 利用fork.exec切换 1.2 利用网关切换 1.3 微服务 - 进程切换注意要点 [2] 动态库替换 [3] 脚本语言热更新 热 ...

  6. 大数据WEB阶段(二十)更新丢失

    更新丢失 一.更新丢失概述 两个并发的事务 , 基于同一个查询进行更新操作 ,后提交的事务忽略了先提交的事务对数据库的影响 , 结果造成了数据库操作失误的问题, 称之为更新丢失. 二.实例 重复充值 ...

  7. 一步步手动实现热修复(二)-类的加载机制简要介绍

    *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 本节课程主要分为3块: 1.一步步手动实现热修复(一)-dex文件的生成与加载 2.一步步手动实现热修复(二)-类的加载机制简要介 ...

  8. (三)matplotlib3.0画三维图(二维热图)

    教程示例 """ matplotlib3.0三维图 mayuhua 2020.5.17 """from mpl_toolkits impor ...

  9. SDL Trados 2019 和 SDL Trados 2021 二零二一五月更新

    SDL Trados 2019 和 SDL Trados 2021 二零二一五月更新 好久没检查更新了 检查地址 https://update.sdl.com/updates/update1/stud ...

  10. 微信小程序更新二维数组中的对象或数组的属性值

    微信小程序更新二维数组中的对象或数组的属性值,这里可能有两种情况 1.微信小程序更新二维数组中的对象的属性值 更新二维数组中的某个对象的属性值,代码如下 js 代码 data: {familys:[{ ...

最新文章

  1. SEL:世界土壤日Stefan Geisen报告(朱永官院士主持,12月4日)
  2. X-Content-Type-Options: nosniff
  3. python json有什么用_为什么要学习用Python解析JSON数据?
  4. docker网络之macvlan
  5. java创建和销毁一个对象_有效的Java –创建和销毁对象
  6. 什么是换码符(escape character)?
  7. 学计算机的如何学英语,怎么在电脑上学习英语
  8. vscode 调试.net core 2.0 输出乱码解决方法
  9. 【基础】集成学习 (Ensemble Learning)
  10. flex的简介(来自百度百科)
  11. MCP2515收发程序 CAN总线 CAN程序 CAN通信 5K-1M波特率 STM32+MCP2515
  12. 白话区块链 之2: 区块链技术理念
  13. 使用md5对文件去重
  14. Vue + Spring Boot 项目实战(十一):用户角色权限管理模块设计
  15. 看不懂简明python教程_简明python教程的读书笔记(一)
  16. 2018个人年度总结:我是如何从嵌入式开发到服务器开发对接天猫精灵、小爱智能音箱服务器!懵懂 | 奋斗 | 进阶 | 信心
  17. 安装maven时安照说明配置环境变量JAVA_HOME
  18. 温故而知新--Java基础(三):Java常用集合类(上)
  19. web前端开发小工具集合
  20. 使用免费工具WCAT为Web应用程序进行压力测试

热门文章

  1. python3_面向对象
  2. (6.1)MATLAB机器人正、逆解中姿态求解的欧拉角的说明
  3. Mac OSX中设置路由
  4. 局域网服务器文件夹隐藏,共享文件设置隐藏 隐藏共享文件夹的方法
  5. ps 画中间透明的边框图形
  6. html背景图片不重叠铺满,css背景图片怎么铺满
  7. php wordphp 读取图片,利用PHPWORD类替换word模版文字,图片等
  8. Git版本控制管理——远程版本库
  9. 在网页中搜索指定内容和以PDF格式保存网页
  10. $().each() 和 $.each()