Unity代码剥离导致ResourceManagerRuntimeData为空

Unity代码剥离为High,代码剥离,但我们遇到了 Addressables 包的问题。由于使用反射,ProviderOperation 被剥离。导致ResourceManagerRuntimeData为空

大概报错如下:

MissingMethodException: Default constructor not found for type UnityEngine.ResourceManagement.AsyncOperations.ProviderOperation`1[[UnityEngine.AddressableAssets.Initialization.ResourceManagerRuntimeData, Unity.Addressables, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
  at System.RuntimeType.CreateInstanceMono (System.Boolean nonPublic) [0x0007b] in <71d402037f2643fe94cabbbe0d22d04d>:0
  at System.RuntimeType.CreateInstanceSlow (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Threading.StackCrawlMark& stackMark) [0x00009] in <71d402037f2643fe94cabbbe0d22d04d>:0
  at System.RuntimeType.CreateInstanceDefaultCtor (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Threading.StackCrawlMark& stackMark) [0x00027] in <71d402037f2643fe94cabbbe0d22d04d>:0
  at System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic) [0x00020] in <71d402037f2643fe94cabbbe0d22d04d>:0
  at System.Activator.CreateInstance (System.Type type) [0x00000] in <71d402037f2643fe94cabbbe0d22d04d>:0
  at UnityEngine.ResourceManagement.Util.LRUCacheAllocationStrategy.New (System.Type type, System.Int32 typeHash) [0x00055] in D:\Project\Designer\Designer\Library\PackageCache\com.unity.addressables@1.1.9\Runtime\ResourceManager\Util\ResourceManagerConfig.cs:134
  at UnityEngine.ResourceManagement.ResourceManager.CreateOperation[T] (System.Type actualType, System.Int32 typeHash, System.Int32 operationHash, System.Action`1[T] onDestroyAction) [0x00032] in D:\Project\Designer\Designer\Library\PackageCache\com.unity.addressables@1.1.9\Runtime\ResourceManager\ResourceManager.cs:358
  at UnityEngine.ResourceManagement.ResourceManager.ProvideResource (UnityEngine.ResourceManagement.ResourceLocations.IResourceLocation location, System.Type desiredType) [0x000d1] in D:\Project\Designer\Designer\Library\PackageCache\com.unity.addressables@1.1.9\Runtime\ResourceManager\ResourceManager.cs:260
  at UnityEngine.ResourceManagement.ResourceManager.ProvideResource[TObject] (UnityEngine.ResourceManagement.ResourceLocations.IResourceLocation location) [0x00001] in D:\Project\Designer\Designer\Library\PackageCache\com.unity.addressables@1.1.9\Runtime\ResourceManager\ResourceManager.cs:287
  at UnityEngine.AddressableAssets.Initialization.InitializationOperation.CreateInitializationOperation (UnityEngine.AddressableAssets.AddressablesImpl aa, System.String playerSettingsLocation, System.String providerSuffix) [0x0009a] in D:\Project\Designer\Designer\Library\PackageCache\com.unity.addressables@1.1.9\Runtime\Initialization\InitializationOperation.cs:42
  at UnityEngine.AddressableAssets.AddressablesImpl.InitializeAsync (System.String runtimeDataPath, System.String providerSuffix) [0x0008d] in D:\Project\Designer\Designer\Library\PackageCache\com.unity.addressables@1.1.9\Runtime\AddressablesImpl.cs:280
  at UnityEngine.AddressableAssets.AddressablesImpl.InitializeAsync () [0x00013] in D:\Project\Designer\Designer\Library\PackageCache\com.unity.addressables@1.1.9\Runtime\AddressablesImpl.cs:289
  at UnityEngine.AddressableAssets.AddressablesImpl.get_InitializationOperation () [0x00013] in D:\Project\Designer\Designer\Library\PackageCache\com.unity.addressables@1.1.9\Runtime\AddressablesImpl.cs:306
  at UnityEngine.AddressableAssets.AddressablesImpl.LoadContentCatalogAsync (System.String catalogPath, System.String providerSuffix) [0x0004c] in D:\Project\Designer\Designer\Library\PackageCache\com.unity.addressables@1.1.9\Runtime\AddressablesImpl.cs:296
  at UnityEngine.AddressableAssets.Addressables.LoadContentCatalogAsync (System.String catalogPath, System.String providerSuffix) [0x00001] in D:\Project\Designer\Designer\Library\PackageCache\com.unity.addressables@1.1.9\Runtime\Addressables.cs:231
  at Ubiant.Common.Adressables.AddressablesLoader+<InitializeAddressables>d__2.MoveNext () [0x00020] in D:\Project\Designer\Designer\Assets\Scripts\Runtime\Addressables\AddressablesLoader.cs:49
  at UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) [0x00027] in <1cc3984764e64bdeb5a66b5d2a3bc7e1>:0
UnityEngine.MonoBehaviour:StartCoroutineManaged2(IEnumerator)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)

 解决方案:

在Assets文件夹里面添加 link.xml文件,内容如下:

 
<linker>
    <assembly fullname="Unity.ResourceManager, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" preserve="all">
    <type fullname="UnityEngine.ResourceManagement.ResourceProviders.LegacyResourcesProvider" preserve="all" />
    <type fullname="UnityEngine.ResourceManagement.ResourceProviders.AssetBundleProvider" preserve="all" />
    <type fullname="UnityEngine.ResourceManagement.ResourceProviders.BundledAssetProvider" preserve="all" />
    <type fullname="UnityEngine.ResourceManagement.ResourceProviders.InstanceProvider" preserve="all" />
    <type fullname="UnityEngine.ResourceManagement.AsyncOperations" preserve="all" />
    </assembly>
    <assembly fullname="Unity.Addressables, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" preserve="all">
    <type fullname="UnityEngine.AddressableAssets.Addressables" preserve="all" />
    </assembly>
</linker>
 

 如果项目中已经存在link.xml文件,直接在link.xml文件中追加以下内容即可:

<assembly fullname="Unity.ResourceManager, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" preserve="all">
    <type fullname="UnityEngine.ResourceManagement.ResourceProviders.LegacyResourcesProvider" preserve="all" />
    <type fullname="UnityEngine.ResourceManagement.ResourceProviders.AssetBundleProvider" preserve="all" />
    <type fullname="UnityEngine.ResourceManagement.ResourceProviders.BundledAssetProvider" preserve="all" />
    <type fullname="UnityEngine.ResourceManagement.ResourceProviders.InstanceProvider" preserve="all" />
    <type fullname="UnityEngine.ResourceManagement.AsyncOperations" preserve="all" />
    </assembly>
    <assembly fullname="Unity.Addressables, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" preserve="all">
    <type fullname="UnityEngine.AddressableAssets.Addressables" preserve="all" />
    </assembly>

参考文章:Addressables and Code Stripping (IL2CPP) - Unity Forum

<think>好的,我现在需要帮助用户解决如何在Unity中禁用代码剥离或资源剥离的问题。首先,我得回忆一下Unity代码剥离机制。Unity在构建项目时,为了减小包体大小,会通过代码剥离(Code Stripping)移除未使用的代码。但有时候这会导致问题,比如反射调用的类或方法被错误地剥离,引发运行时错误,用户提到的引用[3]就提到了这一点。 接下来,我需要整理出禁用或调整代码剥离的方法。根据之前的了解,Unity代码剥离设置主要在Player Settings里。可能需要指导用户进入Project Settings -> Player,找到Code Stripping相关的选项。这里可能需要关闭或调整剥离级别,比如将剥离级别设置为低(Low)或者禁用。不过要注意不同Unity版本可能设置位置不同,可能需要分版本说明。 另外,用户可能还需要保留特定的程序集或类型。例如,使用link.xml文件来指定保留的内容。这时候需要给出一个示例的link.xml配置,说明如何保留整个程序集或特定的命名间。引用[3]中提到反射调用的类会被剥离,所以通过link.xml保留相关代码是关键步骤。 资源剥离方面,用户提到了着色器相关的设置,引用[2]中提到了保持已加载的着色器存活状态。可能需要指导用户在Graphics Settings中调整Shader加载的设置,比如禁用Shader变体剥离或调整预处理程度。此外,资源剥离可能还涉及到其他资源类型,需要检查AssetBundle的Strip选项是否关闭。 还需要考虑不同平台的处理,比如iOS和Android可能在代码剥离上有不同的默认设置,需要提醒用户检查各个平台的单独设置。此外,测试构建后的应用是否仍然存在剥离问题,建议用户进行充分的测试,特别是使用反射的部分。 用户的问题可能还涉及资源剥离的其他方面,比如AssetBundle的剥离设置,所以需要提到在Player Settings中关闭“Strip Unused Bytecode”或其他类似选项。同时,Unity版本的不同可能会导致设置路径或选项名称的变化,需要提醒用户注意版本差异。 最后,应该总结步骤,确保用户能够一步步操作,并且理解每个步骤的作用。同时,生成的相关问题需要覆盖代码剥离的影响、资源剥离的其他设置以及处理反射调用的其他方法,这样用户可以有更全面的了解。</think>在Unity中禁用代码剥离(Code Stripping)或资源剥离(Asset Stripping)的步骤如下: --- ### 1. **禁用代码剥离** #### 方法一:通过Player Settings全局关闭 1. 打开 **Project Settings** -> **Player** 2. 在 **Other Settings** 区域找到 **Code Stripping** 选项: - 对于 **Unity 2021及更高版本**:将 **Managed Stripping Level** 设置为 **Disabled**[^3] - 对于旧版本(如2019):将 **Strip Engine Code** 取消勾选 #### 方法二:通过`link.xml`保留特定代码 在项目根目录创建 `link.xml` 文件,指定需要保留的程序集或命名间: ```xml <linker> <assembly fullname="Assembly-CSharp"> <namespace fullname="YourNamespace" /> <type fullname="YourClassName" /> </assembly> </linker> ``` 此文件会强制Unity保留列出的代码,避免因反射调用被剥离。 --- ### 2. **禁用资源剥离** #### 针对Shader资源的保留 1. 打开 **Project Settings** -> **Graphics** 2. 在 **Shader Loading** 部分: - 勾选 **Keep Loaded Shaders Alive**(保持已加载的着色器)[^2] - 调整 **Shader Variant Preprocessing** 减少变体剥离 #### 针对AssetBundle的剥离 1. 在AssetBundle打包设置中关闭剥离选项: - 取消勾选 **Strip Unused Code** 或 **Strip Unused Components** --- ### 3. **平台特定设置** - **iOS/Android**:在Player Settings的对应平台标签页中,检查代码剥离级别是否为最低(如Low或Disabled) --- ### 4. **测试验证** 构建后通过以下方式验证: - 运行时检查反射调用的类/方法是否存在 - 使用Profiler监控资源加载情况 --- ### 相关问题 1. 代码剥离Unity应用性能有何影响? 2. 如何通过`Preserve`属性标记避免代码剥离? 3. Unity中资源剥离的其他优化方法有哪些? --- 引用文献: [^1]: 反射调用代码剥离导致运行时错误 [^2]: 着色器保留设置减少重新加载开销 [^3]: 通过`link.xml`或调整剥离级别保留代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王 银

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值