Unity 热更新之ILRuntime(一)
一.ILRuntime环境配置
- GitHub: ILRuntime链接
- 创建文件夹Hotfix,Model,ThirdParty
- 配置程序集
三个程序集配置使用非安全代码
告诉Unity,该文件夹或者子文件夹下的脚本都编译到同一个dll里面 - 修改link文件
<linker>
<assembly fullname="Unity.Model" preserve="all"/>
<assembly fullname="Unity.ThirdParty" preserve="all"/>
<assembly fullname="UnityEngine" preserve="all"/>
<assembly fullname="System" preserve="all"/>
</linker>
二.ILRuntime原理
ILRuntime借助Mono.Cecil库来读取DLL的PE信息,以及当中类型的所有信息,最终得到方法的IL汇编码,然后通过内置的IL解译执行虚拟机来执行DLL中的代码。
三.加载流程
- 自动化插件实现自动拷贝Dll和Pdb文件
[InitializeOnLoad]
public class HotFixBuildEditor
{
private const string rootPath = "Library/ScriptAssemblies";
private const string hotFixDll = "Unity.HotFix.dll";
private const string hotFixPdb = "Unity.HotFix.pdb";
private const string targetPath = "Assets/Res/Code";
static HotFixBuildEditor()
{
File.Copy(Path.Combine(rootPath, hotFixDll), Path.Combine(targetPath, hotFixDll + ".bytes"), true);
File.Copy(Path.Combine(rootPath, hotFixPdb), Path.Combine(targetPath, hotFixPdb + ".bytes"), true);
AssetDatabase.Refresh();
Debug.Log("拷贝完成!");
}
}
四.脚本中初始化加载DLL
public class HotFixManager : MonoBehaviour
{
public GameObject obj;
private MemoryStream _dllMs;
private MemoryStream _pdbMs;
private AppDomain _appDomain;
void Start()
{
Load();
}
private void Load()
{
var dllBytes = obj.GetComponent<CodeReferece>().hotfixDll.bytes;
var pdbBytes = obj.GetComponent<CodeReferece>().hotfixPdb.bytes;
#if ILRuntime
Debug.Log("ILRuntime运行成功!!!");
_dllMs = new MemoryStream(dllBytes);
_pdbMs = new MemoryStream(pdbBytes);
_appDomain = new AppDomain();
_appDomain.LoadAssembly(_dllMs, _pdbMs, new PdbReaderProvider());
#else
Assembly.Load(dllBytes, pdbBytes);
#endif
Debug.Log("加载完成!");
}
}