【Unity】热更新原理与 Xlua 配置

热更新

直接理解即是让代码可以像资源包一样被运行时更新。当然它其实还一个名称叫热修复,即实现不重新打包项目也能把 Bug 修好,这也正是它常用的地方。

原理

  1. C# 无法直接热更新

    C# 是编译型语言,需要先编译成 IL 再送到虚拟机里才可运行。部分平台不支持 C# 编译器的使用,所以没法通过直接重新编译 C# 代码来实现热更新。

  2. lua 可以轻松热更新

    lua 是解释性语言,不需要编译,直接在代码中传递字符串给解释器就能运行,所以可以将其作为文本资源对待,更新起来非常轻松。

  3. 不建议完全使用 lua 编程

    解释性语言执行效率低,且 Unity 是 C# 编程环境,开发和学习的难度都会大幅提升。

  4. 在 C# 中混合 lua 实现热更新

    例如在每个 C# 函数的开头加一句判断,如果资源文件里有该函数对应的 lua 文件,才调用 lua 代码,否则说明还不需要热更新,正常调用后续的 C# 代码就行。这样的话只有需要修 Bug 的时候才要编写 lua 代码,否则正常情况可以一直使用 C# 开发。

  5. 手动混合 C# 和 lua 过于麻烦

    必须要求每个函数开头都要加上一段代码,想想就可怕,这工作量太大了,视觉效果也不美观。如果能实现自动把这些代码写上去且只在打包项目时才写上就好了。

  6. 通过 Mono.Cecil 实现 C# 库的自动修改

    C# 首先会被打包成 IL 库,最后才被 IL2CPP 编译成平台代码,IL 的状态下反编译非常容易。利用 Mono.Cecil 我们可以通过程序对这些 IL 库的内容进行调整,比如实现自动修改里面每个函数的代码,从而实现上述需求。

  7. 使用 Xlua 实现上述需求

    Xlua 已经完成了以上需求的实现,并且免费开源,我们可以直接白嫖,又有大厂加持,安全稳定,不说了开冲。

Xlua 热更新

Xlua 在官方的介绍里说是为 Unity 增加了使用 lua 脚本的能力,所以他的功能其实比较多,热更新只是其中一个。在官方文档里,热更新又叫热补丁,热补丁的文档链接如下,必看。

https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/hotfix.md

使用简介

  1. 安装方式不说了,直接去他的仓库看。 https://github.com/Tencent/xLua
  2. 为项目添加 HOTFIX_ENABLE 宏,从而打开热更新功能。
  3. 把所有你需要热更新的代码打上[Hotfix]标签,具体看文档,注意方式一高版本 Unity 用不了。
  4. 搞个单例类,在里面开一个 lua 虚拟机,在里面加载一个文本文件给虚拟机。
  5. 这个加载上来的文本文件就是写 lua 热更新代码的地方,即出了 bug 需要替换上的新代码。
  6. lua 热更新代码里主要是调用 xlua.hotfix 函数实现代码替换,具体看文档。
  7. 点击菜单项 XLua/Generate Code,然后直接打包游戏就行,Xlua 会自动按之前说过的原理修改标记好函数使其支持热更新。

注意点

  1. 高版本 Unity 中所有打标签方式都请使用文档中打[Hotfix]标签的方式二。

  2. 使用 IL2CPP 时,仅 lua 中用到的类有可能会被字节代码剥离程序删除。

    IL2CPP 的过程中会自动删除没有被使用无效代码,而 lua 中调用 C#代码的方式有点类似于反射,这种间接的类型访问方式无法被 IL2CPP 程序识别,因而会导致相关代码被错误的剥离。

    推荐打上[LuaCallCSharp]或[ReflectionUse]标签来解决这个问题,这样 XLua 便能自动把这些类型配置为不可被剥离。

  3. GenerateCode 前建议先调用 ClearGenerateCode,这样才能保证生成的文件确实和代码中设置的一致。

其他猜想

  1. 为什么 C# 变 C++ 代码后,代码结构剧变,lua 也能正常调用?

    C# 访问函数的方式不是直接使用地址,而是先用符号(函数名)去检索地址,然后再跳转到该地址。IL2CPP 中虽然 C# 代码被转换,但这种访问方式被保留了下来,其符号信息就存在 global-metadata.dat 文件中,所以 lua 使用 C# 中的名称也能正常访问。

总结

抛开细节不谈还是蛮简单的,不说了学 lua 去了。

【Unity】热更新原理与Xlua配置的更多相关文章

  1. 深入理解xLua热更新原理

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

  2. 深入理解xLua基于IL代码注入的热更新原理

    目前大部分手游都会采用热更新来解决应用商店审核周期长,无法满足快节奏迭代的问题.另外热更新能够有效降低版本升级所需的资源大小,节省玩家的时间和流量,这也使其成为移动游戏的主流更新方式之一. 热更新可以 ...

  3. Unity 热更新XLua

    什么是冷更新 开发者将测试好的代码,发布到应用商店的审核平台,平台方会进行稳定性及性能 测试.测试成功后,用户即可在AppStore看到应用的更新信息,用户点击应用更 新后,需要先关闭应用,再进行更新 ...

  4. Unity3D热更新之LuaFramework篇[08]--热更新原理及热更服务器搭建

    前言 前面铺垫了这么久,终于要开始写热更新了. Unity游戏热更新包含两个方面,一个是资源的更新,一个是脚本的更新. 资源更新是Unity本来就支持的,在各大平台也都能用.而脚本的热更新在iOS平台 ...

  5. 另类Unity热更新大法:代码注入式补丁热更新

    对老项目进行热更新 项目用纯C#开发的? 眼看Unity引擎热火朝天,无数程序猿加入到了Unity开发的大本营. 一些老项目,在当时ulua/slua还不如今天那样的成熟,因此他们选择了全c#开发:也 ...

  6. ElasticStack系列之七 & IK自动热更新原理与实现

    一.热更新原理 elasticsearch开启加载外部词典功功能后,会每60s间隔进行刷新字典.具体原理代码如下所示: public void loadDic(HttpServletRequest r ...

  7. 【热更新IK词典】ElasticSearch IK 自动热更新原理与实现

    一.热更新原理 elasticsearch开启加载外部词典功功能后,会每60s间隔进行刷新字典.具体原理代码如下所示: public void loadDic(HttpServletRequest r ...

  8. webpack与browser-sync热更新原理深度讲解

    本文首发于CSDN网站,下面的版本又经过进一步的修订.原文:webpack与browser-sync热更新原理深度讲解本文包含如下内容: webpack-hot-middleware EventSou ...

  9. unity热更新方案对比

    Unity应用的iOS热更新 •  什么是热更新 •  为何要热更新 •  怎样在iOS 上对Unity 应用进行热更新 •  支持Unity iOS 热更新的各种Lua 插件的对照 什么是热更新 • ...

  10. Unity热更新对比

    https://www.jianshu.com/p/f9d90edf4a7c Unity 热更新为啥用Lua 详解 ILRuntime的优势 同市面上的其他热更方案相比,ILRuntime主要有以下优 ...

随机推荐

  1. uniapp+vue3酒店预订|vite5+uniapp预约订房系统模板(h5+小程序+App端)

    自研uni-app+vue3+uv-ui跨三端仿同程/携程酒店预订系统Uni-Vue3-WeTrip. uniapp-vue3-wetrip原创基于vite5+uniapp+pinia2+uni-ui ...

  2. 数据万象盲水印 - AIGC的“保护伞”

    导语 近期AIGC的爆火让人们觉得AI似乎无所不能,打工人们已然将 AI 发展成了工作的一大助手,但同样也伴随着很多AI的受害者.一些专家.画家.学者们发现自己的"作品风格"正在被 ...

  3. flutter问题汇总

    Text文字居中 Text(           'You will need to post a photo before you can play!',           textAlign:  ...

  4. Python__FLASK__MySQL基础

    1.数据库的基本操作 创建数据库:使用"CREATE DATABASE 数据库名:"语句创建新的数据库 查看数据库:使用"SHOW DATABASES:"语句查 ...

  5. 将现有的系统环境文件打包成Docker镜像文件

    一.现有A系统Centos7操作: 备注:A系统里最好不安装Docker,否则会报错 卸载不必要软件包 yum remove -y iwl* *firmware* --exclude=kernel-f ...

  6. C#中Newtonsoft.Json(Json.NET)的使用

    C#中Newtonsoft.Json(Json.NET)的使用. 添加引用: using Newtonsoft.Json; 调用代码: //获取图书列表 List<BookInfo> bo ...

  7. Python学习(一)——配套《PyTorch深度学习实战》

    记录一下Python学习过程中的一些问题: 1. 在JupyterLab中查询当前文件的地址 import os print(os.getcwd()) #查询该文件的地址 2. 新建cell 在 Ju ...

  8. 前端学习openLayers配合vue3(加载线上数据源)

    现在我们学习一下加载网上的线上数据再加上点矢量图层,紧接着上一步 关键代码 layers: [ //瓦片图层source第三方,或者自带的,地图的底层 new TileLayer({ // sourc ...

  9. ffmpeg实现视频的合成与分割

    视频合成与分割程序使用   作者开发了一款软件,可以实现对视频的合成和分割,界面如下: 下载该程序 播放时,可以选择多个视频源:在选中"保存视频"情况下,会将多个视频源合成一个视频 ...

  10. WPF中webview2鼠标移动窗体

    WPF里webview2会一直处于其他控件最上层,是个历史遗留问题. 为了能在webview2里鼠标移动让窗体跟着移动位置代码如下: async Task InitializeAsync() { Ap ...