【Unity实战】HybridCLR热更快速集成

本文假设你已经通过UPM导入了HybridCLR、Addressables、il2cpp支持并具有一定的C#基础和Unity编辑器操作能力。

热更程序集

由于本文主打快速集成,故将Assembly-CSharp划入到热更新DLL。理论上成熟的项目应该用Assembly Definition进行精细划分以便于管理和缩短编译时间。但是若掌握不好,划分不明白,可能会出现交叉引用导致反射机制原地GG。

有关Assembly Definition,请见官方文档。

Unity - Manual: Assembly definitions

打开Project Settings, 找到Hybrid Settings,手动将Assembly-CSharp添加到热更新DLL范围内。

如果你有Assembly Definition,也请添加到红框上方的属性中。请注意,热更新Assembly Definition和热更新dlls属于“并且”关系,不能存在相同项。

比如你把Assembly Definition的名写到了底下热更新dlls里头了,然后上面热更新Assembly Definition那里你还把你刚才手动填名字的Assembly Definition给拖进去了。

另起一个热更入口程序集和场景

由于Assembly-CSharp为热更新DLL,那么客户端拉取热更资源的逻辑就不能放在Assembly-CSharp,否则反射机制不起作用,还带来报错。

在这个程序集的同级目录或者子级目录起一个热更入口脚本,具体怎么拉Addressables更新这里就省略了,加载热更DLL的逻辑可参考如下:

    /// <summary>
	/// 加载热更的DLL
	/// </summary>
	IEnumerator LoadHotfixDLLs()
	{
#if !UNITY_EDITOR
        // 读取的热更dll
        var hotFixDllLabelHandle = Addressables.LoadAssetsAsync<TextAsset>("HotUpdateDLL", null);
        yield return hotFixDllLabelHandle;
        var hotFixDlls = hotFixDllLabelHandle.Result;
        Addressables.Release(hotFixDllLabelHandle);
        // 加载获得的dll
        foreach (var hotFixDll in hotFixDlls) {
            Assembly.Load(hotFixDll.bytes);
        }
        Debug.Log("[HotUpdater] LoadHotfixDLLs complete!");
#endif
		yield return null;
	}
	/// <summary>
	/// 加载aot的DLL
	/// </summary>
	/// <returns></returns>
	IEnumerator LoadMetadataForAOTDLLs()
	{
#if !UNITY_EDITOR
		HomologousImageMode mode = HomologousImageMode.SuperSet;
        var aotMetadateDllHandle = Addressables.LoadAssetsAsync<TextAsset>("AOTMetadataDLL", null);
        yield return aotMetadateDllHandle;
        var AOTMetadataDlls = aotMetadateDllHandle.Result;
        foreach (var AOTMetadataDll in AOTMetadataDlls)
        {
            LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(AOTMetadataDll.bytes, mode);
            Debug.Log($"[HotUpdater] LoadMetadataForAOTAssembly:{AOTMetadataDll.name}. mode:{mode} ret:{err}");
        }
        Addressables.Release(aotMetadateDllHandle);
		Debug.Log("[HotUpdater] LoadMetadataForAOTDLLs complete!");
#endif
		yield return null;
	}

	IEnumerator EnterGame()
	{
		yield return LoadMetadataForAOTDLLs();
		yield return LoadHotfixDLLs();
		Addressables.LoadSceneAsync("MainMenu").Completed += (obj) =>
		{
			if (obj.Status == AsyncOperationStatus.Succeeded)
			{
				Debug.Log("[HotUpdater] Successfully load into MainMenu.");
			}
			else
			{
				Debug.LogError("[HotUpdater] Failed to load MainMenu scene!");
			}
		};
	}

简而言之就是加载完热更DLL后和AOT元数据DLL后再进入你游戏的主场景(或者说有引用Assembly-CSharp代码的东西)。

这里笔者假定你的热更新DLL以及元数据DLL在Addressables里各自有标签,于是全拉出来进行Assembly.Load。

你可能会注意到宏,编辑器环境下测试是不能读取热更DLL的,因为属于同一个程序集加载了两遍,浪费不说还带来问题。

编译热更新DLL和AOT元数据DLL

元数据DLL是个新词,也是HybridCLR的牛逼之处。用大白话讲,那些你引用的System命名空间、Newtonsoft.Json等等这些不需要热更新的库都算作AOT元数据DLL。

单击All进行热更新DLL编译。

编译完成后,你的工程文件夹下会有热更新DLL和元数据,你可以在Assets文件夹下另起一个存热更DLL的文件夹,并将图中文件夹里的内容拷贝进去。

有关元数据DLL,不是所有的dll都需要拷贝,你可以看一下你工程里有一个叫AOTGenericReferences,那里有一个表。

但是别回到Unity Editor刷新,Unity会当成程序集导入,你需要改一下后缀名。

将DLL加到Addressables

你可以用Label标签进行区分,案例中用的代码是用label进行区分和加载。

Addressables系统设置

勾选Build Remote Catalog,配置Build和Load路径为Remote

Build Settings设置

理论上你只需要把热更入口场景打进去就行,其他都不要。

允许通过HTTP下载(可选)

如果你测试环境用的网页服务器没有配置HTTPS,那么你需要把这个改成allowed,否则Addressables下载流程可能不会走。

然后走打包流程即可,现在你可以用打包出来的客户端进行测试了。祝好运!

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>