Unity 托管代码剥离

如果项目很大,代码量很多,不仅会使包体变大,编译时间变长,还会导致各种编译报错。比如:

ARM64 branch out of range (154869072 max is +/-128MB)

Unity提供了一种被称作托管代码剥离( managed code stripping )的方案用来删除未使用或无法访问的代码。托管代码剥离从托管程序集中删除代码,包括从项目中的 C# 脚本构建的程序集、作为包和插件一部分的程序集,以及 .NET Framework 中的程序集。

Unity 使用称为 Unity 链接器(Unity linker)的工具对项目程序集中的代码执行静态分析。静态分析识别在执行期间无法访问的任何类、类的部分、函数或函数的部分。此分析仅包括构建时存在的代码,因为在 Unity 执行静态分析时不存在运行时生成的代码。可以使用 托管剥离级别来控制剥离的程度。

配置托管代码剥离:

转到编辑 > 项目设置 > 播放器。
在其他设置中,找到优化一栏。
在这里插入图片描述

将 Managed Stripping Level 属性设置为所需的值。
属性 功能
Disabled 不会移除任何代码。如果使用 mono ,这是默认设置
Minimal 只在 UnityEngine 和 .net 类库中搜索未使用的代码。不会删除任何用户编写的代码。此设置最不可能导致任何意外的运行时行为如果使用 IL2CPP ,这是默认设置。

Managed Stripping Level 等级设置

Low Unity会搜索一些用户编写的程序集,以及所有 UnityEngine和 .net 类库来寻找未使用的代码。此设置应用一组规则,这些规则删除一些未使用的代码,但将意外后果的可能性降到最低,例如使用反射的运行时代码的行为更改。
Medium Unity 部分搜索所有程序集以查找无法访问的代码。此设置应用一组规则,这些规则剥离更多类型的代码模式以减少构建大小。尽管 Unity 不会删除所有可能无法访问的代码,但此设置确实会增加发生不良或意外行为更改的风险。
High Unity会对所有程序集进行广泛搜索,以找到无法访问的代码。在这个设置中,Unity优先考虑的是减少大小,而不是代码稳定性,并删除尽可能多的代码。这种搜索可能比较低的剥离级别花费更长的时间。彻底测试你的应用,仔细使用[Preserve]属性和link.xml文件,以确保Unity链接器不会剥离关键代码。
使用 托管代码剥离 需谨慎,防止必要的代码被剥离。我们可以使用 Preserve 或 Link.xml 来保护代码。

Preserve:
可以使用 Preserve 来防止 Unity 链接器剥离代码的特定部分。如果您的应用程序生成 Unity 执行静态分析时不存在的运行时代码,这将很有帮助;例如,通过反射。Preserve 要么为 Unity 链接器提供关于它不应该剥离哪些代码模式的一般指导,要么提供不剥离特定的、已定义的代码部分的指令。

例如:

class Foo
{
    [Preserve]
    public void PreservedMethod(){}
}

Link.xml :
也可以在项目中包括一个名为 link.xml 的 .xml 文件,以保留特定程序集或程序集的一部分的列表。xml 文件必须存在于 Assets 文件夹或项目中的 Assets 文件夹的子目录中,并且文件中必须包含 标记。Unity 链接器将保存在 link.xml 文件中的任何程序集、类型或成员视为根类型。

例如:

<!--No "preserve" attribute and no members specified means preserve all members-->
<type fullname="AssemblyName.MethodName"/>

<!--Preserve all fields on a type-->
<type fullname="AssemblyName.MethodName" preserve="fields"/>

<!--Preserve all fields on a type-->
<type fullname="AssemblyName.MethodName" preserve="methods"/>

<!--Preserve the type only-->
<type fullname="AssemblyName.MethodName" preserve="nothing"/>

<!--Preserving only specific members of a type-->
<type fullname="AssemblyName.MethodName">
    
  <!--Fields-->
  <field signature="System.Int32 FieldName" />

  <!--Preserve a field by name rather than signature-->
  <field name="FieldName" />
  
  <!--Methods-->
  <method signature="System.Void MethodName()" />

  <!--Preserve a method with parameters-->
  <method signature="System.Void MethodName(System.Int32,System.String)" />

  <!--Preserve a method by name rather than signature-->
  <method name="MethodName" />

  <!--Properties-->

  <!--Preserve a property, it's backing field (if present), 
      getter, and setter methods-->
  <property signature="System.Int32 PropertyName" />

  <property signature="System.Int32 PropertyName" accessors="all" />

  <!--Preserve a property, it's backing field (if present), and getter method-->
  <property signature="System.Int32 PropertyName" accessors="get" />

  <!--Preserve a property, it's backing field (if present), and setter method-->
  <property signature="System.Int32 PropertyName" accessors="set" />

  <!--Preserve a property by name rather than signature-->
  <property name="PropertyName" />

  <!--Events-->

  <!--Preserve an event, it's backing field (if present), add, and remove methods-->
  <event signature="System.EventHandler EventName" />

  <!--Preserve an event by name rather than signature-->
  <event name="EventName" />

</type>
详细请参考 Unity 官方文档:

https://docs.unity.cn/cn/current/Manual/ManagedCodeStripping.html
如果你做了托管代码剥离,但是在IOS还是会报ARM64 branch out of range,那么 你可以打开Xcode工程进行如下设置:

优化等级设为 -Os
把主工程和UnityFramework工程的优化等级都设为 -Os

在这里插入图片描述

转自:https://www.jianshu.com/p/23ee1a176a90

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值