在工程打包后,运行报错
MissingMethodException:AOT generic method not instantiated in aot.assembly:mscorlib.dll,method:System.Collections.Generic.Dictionary`2+Enumerator[FormName,System.Int64]System.Collections.Generic.Dictionary`[FormName,System.Int64]::GetEnumerator()

该问题是因为AOT泛型函数实例化缺失导致的,所以需要补充元数据。HybridCLR官方提供了一种解决方案:基于补充元数据的泛型函数实例化技术(HybridCLR的专利技术)
官方文档可参考:AOT泛型 | HybridCLR
操作步骤
第一步
1、该操作可以收集热更新中用到的AOT泛型实例,生成的裁剪后的AOT dll可以用于补充元数据

HybridCLR会自动把dll文件复制到{project}/HybridCLRData/AssembliesPostIl2CppStrip/{target}文件夹下


第二步
选择最常用的几个dll文件,复制到工程中,并进行添加后缀.bytes(可以用于资源热更新)

"mscorlib"
"System"
"System.Core"
"Assembly-CSharp"
"Google.Protobuf"
第三步
流程说明:运行时在加载热更dll后,再进行加载补充元数据dll(即上文中操作的dll.bytes文件),最后再进行初始化场景和处理其他游戏逻辑。
加载补充元数据示例代码
cs
public void OnInit()
{
StartCoroutine(LoadAOTMetadata());
}
IEnumerator LoadAOTMetadata()
{
// 前三个是系统自带,推荐带上,第四个是自己游戏AOT的程序集
var AotAssemblyDlls = new string[] {
"mscorlib",
"System",
"System.Core",
"Assembly-CSharp",
"Google.Protobuf"
};
for (var i = 0; i < AotAssemblyDlls.Length; i++)
{
var aotDllName = AotAssemblyDlls[i];
var path = $"Assets/HotUpdate/MetaDataDlls/{aotDllName}.dll.bytes";
var handle = Addressables.LoadAssetAsync<TextAsset>(path);
yield return handle;
handle.Completed += (asset) =>
{
LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(asset.Result.bytes,HomologousImageMode.SuperSet);
if (err == LoadImageErrorCode.OK)
Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. ret:{err}");
else
Debug.LogError($"LoadMetadataForAOTAssembly:{aotDllName}. ret:{err}");
};
}
//开始处理场景初始化和游戏逻辑
}
注意事项
1、PatchedAOTAssemblyList列表的计算结果是保守的,实践中很可能不需要补充这么多。如果没有明显的内存压力,直接按列表全补充比较省事。如果需要优化则可以只补充最常见的几个dll(如mscorlib之类),后面遇到AOT泛型错误再加上相应的dll。补充元数据dll是可以热更的,不用担心发布后在某个版本突然遇到泛型错误的问题。
2、目前支持两种元数据模式:
|------------------------------------|--------------------------------------------------------------------------|
| HomologousImageMode.Consistent | 即补充的dll与打包时裁剪后的dll精确一致。因此必须使用build过程中生成的裁剪后的dll,则不能直接复制原始dll。 |
| HomologousImageMode.SuperSet | 即补充的dll是打包时裁剪后的dll的超集。这个模式放松对了AOT dll的要求,你既可以用裁剪后的AOT dll,也可以用原始AOT dll。 |
3、使用补充元数据方案是免费的,补充元数据加载后,大约会占用6倍dll大小的内存,而且这些内存无法回收。如果对内存有较高的要求,请使用商业版本的完全泛型共享技术,不再需要补充元数据,节省这部分内存。
4、如果补充元数据的dll作为额外数据文件也打入了主包(例如放到StreamingAssets下),则主工程启动时加载更优。
5、不同BuildTarget平台的裁剪AOT dll不可复用。
