unity python热更新_Unity C#热更新方案 ILRuntime学习笔记(一) Hello World

article/2025/10/22 23:48:05

一、ILRuntime介绍

问:什么是热更新?

答:软件在使用时就能实现更新的方式就叫做热更新。热更新无需用户重新下载安装或重启,在使用时即可更新,方便快捷体验良好。

问:什么是ILRuntime?

答:ILRuntime是一个C#热更新方案。ILRuntime项目为基于C#的平台(例如Unity)提供了一个纯C#实现,快速、方便且可靠的IL运行时,使得能够在不支持JIT的硬件环境(如iOS)能够实现代码的热更新

问:lua 和 ILRuntime哪个热更新方案更好?

答:如果你的团队更熟悉lua,就用lua。如果你的团队更熟悉C#就用ILRuntime。如果你是主程,你可以选择自己喜欢的方案,但是要肩负起填坑的责任。

我个人的感觉是:lua在Unity中用起来很难受,不是lua这门语言不好,而是因为在Unity中官方的开发语言是C#。用lua就意味着开发者要会两种语言,学习和开发成本都高,而且因为C#是强类型、面向对象的语言。lua是弱类型,非面向对象的语言。

lua从编程思想和代码写法都和C#有较大差距,这一点在面对越大的项目时感受越明显,项目小的时候觉得lua还好,项目做大了以后会发现lua带给你的麻烦会大于便利。

而ILRuntime方案是基于C#的,开发语言统一,编码更容易。不过他的缺点是实际经过验证的项目还是太少了,不太成熟,可能有很多坑需要填,不像是经过很多项目验证的lua,有比较成熟的方案。

二、下载ILRuntime

先去GitHub上点个赞,支持一下该项目,再去Unity Demo上把项目下载下来,顺便也点个赞。

如果国外地址下载慢,可以在国内码云上下载Demo。

c2d47ec6ad4c99e56b4fefaf508c9c76.png

三、导入ILRuntime

1.解压缩Unity Demo

打开Unity工程目录下的ProjectSettings/ProjectVersion.txt 查看工程版本。

为了避免因为不同版本导致的兼容问题,工程版本和Unity版本尽量保持一致,我下载的Demo工程版本是2019.3.6f1, 我尽量用2019.3.6 或稍微高一点儿的版本导入。

20cde4f78d072f16399c7911cd2cbad0.png

2.目录结构

工程导入完毕,看下目录结构。

Demo目录:

在Samples/ILRuntime/1.6.2/Demo/_Scenes/Examples文件夹下

e60bf83a8c36a17ce8a67194045847eb.png

热更新加载的代码目录:

热更新代码会从StreamingAssets目录下加载编译后的dll

其中mdb和pdb文件都是调试时用的,发布时只需要dll。

f857d885cd2ea096289c0e51eb8ea92f.png

运行Hello World Demo:

打开并运行 01_Hello World 场景。可以看到控制台输出了如下结果。

2c1e391835ff7ac0b7d503c650bac62b.png

ILR是如何工作的呢?看下HelloWorld脚本。

using UnityEngine;

using System.Collections;

using System.IO;

using ILRuntime.Runtime.Enviorment;

public class HelloWorld : MonoBehaviour

{

//AppDomain是ILRuntime的入口,最好是在一个单例类中保存,整个游戏全局就一个,这里为了示例方便,每个例子里面都单独做了一个

//大家在正式项目中请全局只创建一个AppDomain

AppDomain appdomain;

System.IO.MemoryStream fs;

System.IO.MemoryStream p;

void Start()

{

StartCoroutine(LoadHotFixAssembly());

}

IEnumerator LoadHotFixAssembly()

{

//首先实例化ILRuntime的AppDomain,AppDomain是一个应用程序域,每个AppDomain都是一个独立的沙盒

appdomain = new ILRuntime.Runtime.Enviorment.AppDomain();

//正常项目中应该是自行从其他地方下载dll,或者打包在AssetBundle中读取,平时开发以及为了演示方便直接从StreammingAssets中读取,

//正式发布的时候需要大家自行从其他地方读取dll

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

//这个DLL文件是直接编译HotFix_Project.sln生成的,已经在项目中设置好输出目录为StreamingAssets,在VS里直接编译即可生成到对应目录,无需手动拷贝

//工程目录在Assets\Samples\ILRuntime\1.6\Demo\HotFix_Project~

//以下加载写法只为演示,并没有处理在编辑器切换到Android平台的读取,需要自行修改

#if UNITY_ANDROID

WWW www = new WWW(Application.streamingAssetsPath + "/HotFix_Project.dll");

#else

WWW www = new WWW("file:///" + Application.streamingAssetsPath + "/HotFix_Project.dll");

#endif

while (!www.isDone)

yield return null;

if (!string.IsNullOrEmpty(www.error))

UnityEngine.Debug.LogError(www.error);

byte[] dll = www.bytes;

www.Dispose();

//PDB文件是调试数据库,如需要在日志中显示报错的行号,则必须提供PDB文件,不过由于会额外耗用内存,正式发布时请将PDB去掉,下面LoadAssembly的时候pdb传null即可

#if UNITY_ANDROID

www = new WWW(Application.streamingAssetsPath + "/HotFix_Project.pdb");

#else

www = new WWW("file:///" + Application.streamingAssetsPath + "/HotFix_Project.pdb");

#endif

while (!www.isDone)

yield return null;

if (!string.IsNullOrEmpty(www.error))

UnityEngine.Debug.LogError(www.error);

byte[] pdb = www.bytes;

fs = new MemoryStream(dll);

p = new MemoryStream(pdb);

try

{

appdomain.LoadAssembly(fs, p, new ILRuntime.Mono.Cecil.Pdb.PdbReaderProvider());

}

catch

{

Debug.LogError("加载热更DLL失败,请确保已经通过VS打开Assets/Samples/ILRuntime/1.6/Demo/HotFix_Project/HotFix_Project.sln编译过热更DLL");

}

InitializeILRuntime();

OnHotFixLoaded();

}

void InitializeILRuntime()

{

#if DEBUG && (UNITY_EDITOR || UNITY_ANDROID || UNITY_IPHONE)

//由于Unity的Profiler接口只允许在主线程使用,为了避免出异常,需要告诉ILRuntime主线程的线程ID才能正确将函数运行耗时报告给Profiler

appdomain.UnityMainThreadID = System.Threading.Thread.CurrentThread.ManagedThreadId;

#endif

//这里做一些ILRuntime的注册,HelloWorld示例暂时没有需要注册的

}

void OnHotFixLoaded()

{

//HelloWorld,第一次方法调用

appdomain.Invoke("HotFix_Project.InstanceClass", "StaticFunTest", null, null);

}

private void OnDestroy()

{

if (fs != null)

fs.Close();

if (p != null)

p.Close();

fs = null;

p = null;

}

void Update()

{

}

}

惊喜!注释是纯中文的,作者一定是中国人!注释很详细,看注释就行了。

其中比较重要的代码是:

//这个DLL文件是直接编译HotFix_Project.sln生成的,已经在项目中设置好输出目录为StreamingAssets,在VS里直接编译即可生成到对应目录,无需手动拷贝

//工程目录在Assets\Samples\ILRuntime\1.6\Demo\HotFix_Project~

//以下加载写法只为演示,并没有处理在编辑器切换到Android平台的读取,需要自行修改

WWW www = new WWW("file:///" + Application.streamingAssetsPath + "/HotFix_Project.dll");

//HelloWorld,第一次方法调用

appdomain.Invoke("HotFix_Project.InstanceClass", "StaticFunTest", null, null);

打开HotFix_Project:

HotFix_Project 是Demo自带的C#热更新代码工程。

工程目录在

Assets\Samples\ILRuntime\1.6\Demo\HotFix_Project~文件夹下,用Visual Studio打开该工程。

注意:HotFix_Project~ 后面带了个波浪号,Unity会自动忽略该目录,资源不会被导入,代码不会被编译,文件不会带进发布包。

具体规则可以看官方文档:

修改热更新代码:

打开HotFix项目下的InstanceClass类 修改StaticFunTest方法中输出的内容:

public static void StaticFunTest()

{

UnityEngine.Debug.Log("调用了热更新类的静态方法!");

}

生成热更新代码dll:

右键项目 > 生成

b131bd7f91d78986d0e12975297c2959.png

重新运行Hello World Demo:

查看输出结果,可以看到 我们修改的内容被输出了。

7ac12fe1f8e5720204520467f9aefda6.png

通过以上步骤,了解了IRuntime的基本运行流程。

1.热更代码生成dll

2.Unity加载dll

3.Unity调用dll里的方法

三、创建自己的Hotfix工程

从零开始创建自己的热更工程,体验完整配置流程。

1.打开Visual Studio,新建项目。

3dde114a90160e36a641050852d11fe2.png

2.修改项目配置

选择类库(.NET Framework)。

修改名称为 Hotfix

fb7f078e283536b4eb8df54850e55b35.png

修改路径为 Unity项目根目录

c364221de605cea67f99f570760160b5.png

3.添加UnityEngine的引用

在Unity中用Visual Studio打开Unity Demo的任意一个脚本,VS会自动关联需要的Unity类库引用,在项目的引用中可以看到引用的dll路径。

e6d30f1f35156c362c71940082135b74.png

在我们自己的Hotfix工程引用中添加该文件。

有两个主要的路径

(1)在Unity安装目录下的Editor\Data

我的电脑路径是:D:\SDK\Unity\2019.4.1f1\Editor\Data\Managed\UnityEngine\

把该文件夹内所有dll文件都引入到Hotfix工程里。

baf543c193f7855c42499ed630ba1dd0.png

(2)在Unity工程根目录下的Library\ScriptAssemblies\

我的电脑路径是:

D:\Projects\Unity3D\Unity 2019.3 Projects\ILRuntimeU3D\ILRuntimeDemo\Library\ScriptAssemblies

添加自己需要的dll,我引用了以下两个dll。

Assembly-CSharp.dll

UnityEngine.UI.dll

注:Unity 2019中已经把类库拆的很零散了,应该是为了解耦,为了以后的规划。他把类库拆成两个部分,内置的类库放在Unity安装目录下了,PackageManager包管理器下载的插件都放在Unity工程目录下了,UGUI的库从内置位置移动到PackageManager里了,可能以后要淘汰掉。

4.编写 Hello World

添加完引用,可以开始写代码了。

在我们自己的Hotfix工程中添加一个类 HelloWorld.cs 并输入以下代码:

namespace Hotfix {

using UnityEngine;

// 冰封百度的Blog:https://segmentfault.com/a/1190000023183723

public class HelloWorld {

public void Test() {

Debug.Log("Hello World");

}

}

}

5.配置Hotfix.dll输出路径

右键Hotfix工程, 选择生成选项卡,在下方的输出路径里浏览到StreamingAssets文件夹或填写相对路径:..\..\Assets\StreamingAssets\

549bd5148bf2705e485af7d304ec0ea0.png

5.生成Hotfix.dll

右键Hotfix工程,选择生成。

生成成功后可以看到如下提示,如果失败则根据错误提示进行处理。

6f5776ab4218e7b76972a3c678da679a.png

6.修改Unity Demo中的HelloWorld脚本

主要修改脚本中加载dll的名称,HotFix_Project改为Hotfix。

并且添加调用热更方法的代码。

修改后如下:

using UnityEngine;

using System.Collections;

using System.IO;

using ILRuntime.Runtime.Enviorment;

public class HelloWorld : MonoBehaviour

{

//AppDomain是ILRuntime的入口,最好是在一个单例类中保存,整个游戏全局就一个,这里为了示例方便,每个例子里面都单独做了一个

//大家在正式项目中请全局只创建一个AppDomain

AppDomain appdomain;

System.IO.MemoryStream fs;

System.IO.MemoryStream p;

void Start()

{

StartCoroutine(LoadHotFixAssembly());

}

IEnumerator LoadHotFixAssembly()

{

//首先实例化ILRuntime的AppDomain,AppDomain是一个应用程序域,每个AppDomain都是一个独立的沙盒

appdomain = new ILRuntime.Runtime.Enviorment.AppDomain();

//正常项目中应该是自行从其他地方下载dll,或者打包在AssetBundle中读取,平时开发以及为了演示方便直接从StreammingAssets中读取,

//正式发布的时候需要大家自行从其他地方读取dll

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

//这个DLL文件是直接编译HotFix_Project.sln生成的,已经在项目中设置好输出目录为StreamingAssets,在VS里直接编译即可生成到对应目录,无需手动拷贝

//工程目录在Assets\Samples\ILRuntime\1.6\Demo\HotFix_Project~

//以下加载写法只为演示,并没有处理在编辑器切换到Android平台的读取,需要自行修改

#if UNITY_ANDROID

WWW www = new WWW(Application.streamingAssetsPath + "/Hotfix.dll");

#else

WWW www = new WWW("file:///" + Application.streamingAssetsPath + "/Hotfix.dll");

#endif

while (!www.isDone)

yield return null;

if (!string.IsNullOrEmpty(www.error))

UnityEngine.Debug.LogError(www.error);

byte[] dll = www.bytes;

www.Dispose();

//PDB文件是调试数据库,如需要在日志中显示报错的行号,则必须提供PDB文件,不过由于会额外耗用内存,正式发布时请将PDB去掉,下面LoadAssembly的时候pdb传null即可

#if UNITY_ANDROID

www = new WWW(Application.streamingAssetsPath + "/Hotfix.pdb");

#else

www = new WWW("file:///" + Application.streamingAssetsPath + "/Hotfix.pdb");

#endif

while (!www.isDone)

yield return null;

if (!string.IsNullOrEmpty(www.error))

UnityEngine.Debug.LogError(www.error);

byte[] pdb = www.bytes;

fs = new MemoryStream(dll);

p = new MemoryStream(pdb);

try

{

appdomain.LoadAssembly(fs, p, new ILRuntime.Mono.Cecil.Pdb.PdbReaderProvider());

}

catch

{

Debug.LogError("加载热更DLL失败,请确保已经通过VS打开Assets/Samples/ILRuntime/1.6/Demo/HotFix_Project/HotFix_Project.sln编译过热更DLL");

}

InitializeILRuntime();

OnHotFixLoaded();

}

void InitializeILRuntime()

{

#if DEBUG && (UNITY_EDITOR || UNITY_ANDROID || UNITY_IPHONE)

//由于Unity的Profiler接口只允许在主线程使用,为了避免出异常,需要告诉ILRuntime主线程的线程ID才能正确将函数运行耗时报告给Profiler

appdomain.UnityMainThreadID = System.Threading.Thread.CurrentThread.ManagedThreadId;

#endif

//这里做一些ILRuntime的注册,HelloWorld示例暂时没有需要注册的

}

void OnHotFixLoaded()

{

//HelloWorld,第一次方法调用

//appdomain.Invoke("HotFix_Project.InstanceClass", "StaticFunTest", null, null);

// 实例化Hotfix中的类

object obj = appdomain.Instantiate("Hotfix.HelloWorld");

appdomain.Invoke("Hotfix.HelloWorld", "Test", obj);

}

private void OnDestroy()

{

if (fs != null)

fs.Close();

if (p != null)

p.Close();

fs = null;

p = null;

}

}

运行Unity,可以看到输出了Hello World

803e28e40c6edf59acb25f7328925599.png

至此,ILRuntime Hello World部分已经全部完成了。

总结:

ILRuntime使用时,除了Hotfix工程的配置稍微麻烦一些外,其他部分都不难,Demo做的很完善,基本是开箱即用。具体使用细节建议仔细阅读官方文档:

http://ourpalm.github.io/ILRu...


http://chatgpt.dhexx.cn/article/0GZfDBpP.shtml

相关文章

基于mediapipe的动作捕捉和Unity的球棍模型同步

基于mediapipe的动作捕捉和Unity的球棍模型同步 所需环境python端unity端效果 所需环境 这是我所使用的环境 python3.9 安装mediapipe和opencv-python包 python和Unity通信使用socket Unity2021.3 python端 如何安装那两个包我就不说了,大家有不明白可以去百度 m…

unity 原型_使用Unity和React快速进行原型制作

unity 原型 Web applications are great way to quickly reach a lot of users without the hassle of native client installs and play store downloads. Web frameworks such as React allow page components to communicate and respond to user interaction much like tra…

使用 命令行/WinForm 来打包Unity可执行程序

使用 命令行/WinForm 来打包Unity可执行程序 前言一、编辑Editor打包工具1.编辑打包脚本2.Unity编辑器中样式 二、命令行调用Unity打包函数1.Unity命令行常用参数2.命令行调用静态打包函数 三、使用WinForm创建可视化操作界面1.可视化界面2.代码详细:①CmdHelper类&…

Unity + Jenkins自动打包 (二)构建Jenkins项目以及编写Python、Unity脚本

1、新建Jenkens项目 在上一篇中,完成了Jenkins的安装和初始化,以及权限设置。 查看上一篇:Jenkins安装 点此 现在打开浏览器,输入http://localhost:8081,当然,需要改成你自己设置的Jenkins端口号&#xff…

unity python服务器_Unity如何连接服务器: 一个简单的例子

Unity3D本身是用来做客户端的通用游戏引擎, 要建立网络连接的话, 其实需要使用的是C#本身的网络和线程模块, 即System.Net.Sockets & System.Threading. 本文中我做了一个简单的例子, 适合那些需要做Unity客户端连接服务器功能的人入门. 整体项目 客户端: 我做的项目主要是…

unity + python socket通信,自定义数据包

unity和python相互之间通过socket通信来发送自定义数据包是一个利用unity构建场景和通过python来做数据处理的方式,能够有效的利用两种不同语言的优势。 我已经将对应的操作封装为对应的一个模块,SocketTools.cs,我们先来看一下具体的代码用…

假设电话收费标准为: (1)国际长途1.00元/分钟,(2) 国内长途0.60元/分钟,(3)市话前3分钟0.20元,3分钟以后0.10元/分钟。现假设某话单文件中每条话单包含如下信息:通话日期(10

你好,帮我做个C语言题目 你好,我是Assistant。很高兴为您做题。 请提供题目的完整题面,并提供任何相关的输入、输出、约束条件等信息。 如果您有任何其他问题,请随时与我联系。我将竭诚为您服务。 897354667qq.com 假设电话收…

电商用户行为数据分析实战(MySQL +PowerBI)

目录 一、项目概况二、数据源三、数据清洗3.1 选择子集导入,匹配适合的数据类型3.2 列重命名3.3重复值处理3.4 缺失值处理3.5 异常值处理从timestamps字段中提取日期数据列查看日期列数据异常情况 四、数据分析4.1 整体购物情况,基于AARRR模型4.1.1 各字…

【业务数据分析】——十大常用数据分析方法

🤵‍♂️ 个人主页:Lingxw_w的个人主页 ✍🏻作者简介:计算机科学与技术研究生在读 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 &#x1f4a…

基于订单的数据分析

目录 项目背景 数据理解 指标维度 指标梳理 维度梳理 导入数据 数据预处理 数据格式整理 规范字段名 增加字段 简化地址 缺失值处理 异常值分析​ 重复值处理 数据分析 描述性统计 总体销售情况 周趋势、日趋势分析 产品价格分析 地区分析 转化率分析 总结…

大数据培训 | 电商用户行为分析之订单支付实时监控

在电商网站中,订单的支付作为直接与营销收入挂钩的一环,在业务流程中非常重要。对于订单而言,为了正确控制业务流程,也为了增加用户的支付意愿,网站一般会设置一个支付失效时间,超过一段时间不支付的订单就…

订单数据分析

订单背景 订单:对订单的预测不仅为了企业更好的制定物料采购计划、控制库存、提升生产效率、控制生产进度,还为了帮助企业更好的把控市场潜在需求,分析目前经营状态和未来发展趋势。 宽厚板材市场价格(只能查询到近三个月的&…

关于订单功能的处理和分析

这两天看了一下RABC的权限管理处理,梳理了一下订单功能的表创建,界面,功能分析。 目录 RABC RBAC0模型 那么对于RABC模型我们怎么创建数据库表? 订单模块的梳理 RABC RABC说的是在用户和权限之间多一个角色,用户与…

订单数据分析-实战

1. 京东订单数据准备 1.1 京东订单数据介绍 2020年5月25日10%抽样数据大家电-家用电器-冰箱70K 1.2 数据清洗 缺失值处理 用户城市和省份信息有部分缺失,部分订单的订单中支付时间为空值数据逻辑错误格式内容一致性 import pandas as pd import numpy as np im…

话单数据完整流程

原始数据__解析_____>>>解析后的数据___入库____>>>汇总的数据 1.原始数据 上游中兴的原始数据,在远程桌面Winscp软件中查看。丢失了下游也没法补充采集。得等上游补充采集后下游才能解析。当原始数据存在,而话单数据显示红点&…

话单分析账单分析行踪分析三合一数据分析

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

Office Tool Plus(安装visio)

说明:需要提前卸载原先的Office(Word、PPT、Excel等) 一、Office Tool Plus官网 https://otp.landian.vip/zh-cn/download.html 二、下载Office Tool Plus 百度网盘链接(Office Tool Plus安装包) 链接:…

FFmpeg音频解码-音频可视化

最近在做一个音频可视化的业务,网上有Java层的实现方法,但是业务需要用C实现,从原理出发其实很简单,先对音频进行解码,再计算分贝。这比把大象放进冰箱还简单。本文从音频可视化的业务为依托,以FFmpeg为基础…

基于FFmpeg的视频播放器之七:音频解码

一.流程 音频解码的流程和视频解码几乎一样,最大的区别是解码后需要进行重采样。因为解码出的AVSampleFormat格式是AV_SAMPLE_FMT_FLTP(float, planar),该格式无法直接使用SDL进行播放,需要转换成SDL支持的AV_SAMPLE_FMT_S16(signed 16 bits)格式。关于重采样,详见下篇…

2020手机音频解码芯片_2020杰理音频芯片全解析,14款音频产品代表作拆解汇总...

珠海市杰理科技股份有限公司,成立于2010年。杰理科技主要从事射频智能终端、多媒体智能终端等系统级芯片(SoC)的研究、开发和销售。 杰理科技的芯片产品主要应用于AI智能音箱、蓝牙音箱、蓝牙耳机、智能语音玩具等物联网智能终端产品,下游应用产品市场十分广泛和巨大。 杰理科…