[Unity实战]热更新如何预防过度裁剪

发布于:2024-05-07 ⋅ 阅读:(28) ⋅ 点赞:(0)

情景再现

假设你现在有一个游戏客户端,客户端只打包了入口场景,游戏场景都存放在了AB包。

你打的热更包里使用了协程中的waituntil修复游戏场景中空投补给资源加载时机问题,但是打出来的热更在真机跑报如下错误:

TypeLoadException: Could not load type 'UnityEngine.WaitUntil' from assembly 'UnityEngine.CoreModule'.

Chest.Start () (at <00000000000000000000000000000000>:0)

UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <00000000000000000000000000000000>:0)

UnityEngine.StackTraceUtility:ExtractStringFromExceptionInternal(Object, String&, String&)

分析

很明显我们的WaitUntil在打包客户端的时候被裁减了,我们的入口程序集并没有使用WaitUntil,即无明显的引用,导致il2cpp直接裁剪。

热更的原理是在已有代码的基础上操作,然而客户端本身没有。

修复

修复方法比较简单,但也希望读者在后续的项目中规划好项目可能要用到的程序集、命名空间、类型等。

根据官方文档,il2cpp会在编译前找一次link.xml,一般位于Assets文件夹下。

华佗在打热更新时也会在HybridCLRData文件夹下生成link.xml,这两个文件其实可以互通。如果你想现阶段临时解决问题,可以将这个link.xml文件复制到Assets文件夹下,然后重新打包和分发客户端。

link示例

link.xml是一个用于配置Unity引擎在构建时进行代码剪裁的文件。它可以通过保留和删除配置来告诉Unity哪些代码需要保留,哪些可以剪裁,以减少构建后的应用程序的体积。

<linker>

  <assembly fullname="Assembly-CSharp">

    <type fullname="MyNamespace.MyClass" preserve="all" />

  </assembly>

</linker>

以上为一个link.xml的示例。在这个示例中,我们告诉Unity保留了一个来自主程序集中名为MyNamespace.MyClass的类型,以确保它不会被剪裁。

也请注意,如果你在Player Settings选的是strict,那么即便你link.xml明确写了保留部分不代表最后打出来的包一定会保留。