HybridCLR热更打包后AOT泛型函数实例化缺失处理

在工程打包后,运行报错

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不可复用。

相关推荐
RReality1 小时前
【Unity Shader URP】序列帧动画(Sprite Sheet)实战教程
unity·游戏引擎
mxwin1 小时前
Unity URP 多线程渲染:理解 Shader 变体对加载时间的影响
unity·游戏引擎·shader
呆呆敲代码的小Y3 小时前
【Unity工具篇】| 游戏完整资源热更新流程,YooAsset官方示例项目
人工智能·游戏·unity·游戏引擎·热更新·yooasset·免费游戏
黄思搏1 天前
基于标注平台数据的 Unity UI 自动化构建工作流设计与工程实践
ui·unity·蓝湖·vectoui
羊羊20352 天前
开发手札:Unity6000与Android交互
android·unity·android-studio
Sator12 天前
Unity AStarPath的踩坑点
unity
星河耀银海3 天前
Unity基础:摄像机Camera的参数设置与视角控制
unity·游戏引擎·lucene
星河耀银海3 天前
Unity基础:Transform组件的位移、旋转与缩放详解
unity·游戏引擎·lucene
海清河晏1113 天前
数据结构 | 单链表
数据结构·unity·dreamweaver
mxwin3 天前
Unity URP 下 MatCap 技术详解 无视光照环境的卡通与质感渲染方案
unity·游戏引擎