Unity ILRuntime

Unity ILRuntime

🎮

环境配置

EmPvcvwEPa.png

1
2
3
4
5
6
<linker>
<assembly fullname="Unity.Model" preserve="all" />
<assembly fullname="Unity.ThirdParty" preserve="all" />
<assembly fullname="UnityEngine" preserve="all" />
<assembly fullname="System" preserve="all" />
</linker>

link.xml 标记了在打包的时候哪些文件类型不被剔除掉


建议
创建的脚本最好放到 Hotfix

或者 Model

要么 放到 ThirdPart

Code_-_Insiders_mqXXBbrHSa.png


有相关的dll文件
可以把依赖文件留着 以后项目也能用

ILRuntime 的实现原理

ILRuntime借助Mono.Cecil库来读取DLL的PE信息,以及当中类型的所有信息,最终得到方法的IL汇编码,然后通过内置的IL解译执行虚拟机来执行DLL中的代码。

扩展接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

//Unity提供的特性 每次编译完脚本都会执行 也就是说启用编辑器就会执行👇
[InitializeOnLoad]
public class BuildHotfixEditor
{
private const string scriptAssembliesDir = "Library/ScriptAssemblies";

//复制到哪个文件夹
private const string codeDir = "Assets/Res/Code/";

//hotfixdll的文件夹
const string hotfixDll = "Unity.Hotfix.dll";

//hotfixpdb的文件夹
const string hotfixPdb = "Unity.Hotfix.pdb";

//⭐
static BuildHotfixEditor()
{
File.Copy(Path.Combine(scriptAssembliesDir,hotfixDll),Path.Combine(codeDir,hotfixDll+".bytes"),true);
File.Copy(Path.Combine(scriptAssembliesDir,hotfixPdb),Path.Combine(codeDir,hotfixPdb+".bytes"),true);
Debug.Log("复制hotfix文件成功");
AssetDatabase.Refresh();
//👆这代码就是相当于在面板刷新了一下,让新的素材显露出来
}
}

Unity主工程 和 热更新工程 的交互

1
2
3
4
5
6
7
8
9
10
11
12
13
void Start()
{
Load();
CallStaticFunction();
}

void CallStaticFunction()
{
//调用没有带参数
appDomain.Invoke("Unity.Hotfix.Init", "Log",null,null);
appDomain.Invoke("Unity.Hotfix.Init", "Log",null,"Hello ILR!");
appDomain.Invoke("Unity.Hotfix.Init", "Log",null, new string[]{"hello","ilr"});
}

所调用的函数区域👇
或许是”重载”由参数自动匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//⭐
namespace Unity.Hotfix
{
public class Init
{
static void Log()
{
Debug.Log("Log1被调用了");
}
static void Log(string text)
{
Debug.Log("Log1被调用了"+text);
}
static void Log(string str1,string str2)
{
Debug.Log("Log1被调用了"+str1+":"+str2);
}
}

}
作者

发布于

2022-12-31

更新于

2023-01-10

许可协议