You can use annotations to prevent the Unity linker from stripping specific sections of your code. This is helpful if your application produces runtime code which doesn’t exist when Unity performs the static analysis; for example, through reflection. Annotations either provide general guidance to the Unity linker about which code patterns it shouldn’t strip, or instructions not to strip a specific, defined section of code.
There are two broad approaches you can use to annotate your code to preserve it from the managed code stripping process:
Each of these techniques provides more control over the amount of code the Unity linker strips at higher stripping levels and reduces the chance of vital code being stripped. Annotations are especially useful when your code references other code through reflection, because the Unity linker can’t always detect uses of reflection.
Preserve code that uses reflection or generates other code at runtime to significantly reduce the likelihood of unexpected behavior when your application is executed. For examples of reflection patterns that the Unity linker can recognize, refer to Unity Intermediate Language Linker reflection test suite.
Root annotations force the Unity linker to treat code elements as roots, which aren’t stripped in the code stripping process. There are two types of root annotations you can use, depending on whether you need to preserve individual types with their constructors or assemblies:
Use the [Preserve]
attribute to individually exclude specific sections of your code from the Unity linker’s static analysis. To annotate a piece of code with this attribute, add [Preserve]
immediately before the first part of the code you want to preserve. The following list describes what entities the Unity linker preserves when you annotate different code elements with the [Preserve]
attribute:
[Preserve]
attribute to an assembly, place the attribute declaration in any C# file included in the assembly, before any namespace declarations.[add]
accessor, and the [remove]
accessor.Use the [Preserve]
attribute when you want to preserve both a type and its default constructor. If you want to keep one or the other but not both, use a link.xml
file.
You can define the [Preserve]
attribute in any assembly and in any namespace. You can use the PreserveAttribute
class, create a subclass of it, or create your own class. For example:
class Foo
{
[Preserve]
public void PreservedMethod(){}
}
You can include a .xml file named link.xml
in your project to preserve a list of specific assemblies or parts of assemblies. The link.xml
file must be present in the Assets
folder or a subdirectory of the Assets
folder in your project and must include the <linker>
tag in the file. The Unity linker treats any assembly, type, or member preserved in a link.xml
file as a root type.
You can use any number of link.xml
files in your project. As a result, you can provide separate preservation declarations for each plug-inA set of code created outside of Unity that creates functionality in Unity. There are two kinds of plug-ins you can use in Unity: Managed plug-ins (managed .NET assemblies created with tools like Visual Studio) and Native plug-ins (platform-specific native code libraries). More info
See in Glossary. You can’t include a link.xml
file in a package, but you can reference package assemblies from non-package link.xml
files.
For information on how to format the link.xml
file, refer to Link XML formatting reference.
Dependency annotations define dependencies between various code elements. These annotations are useful for preserving code patterns that the Unity linker can’t statically analyze, such as reflection. These annotations also ensure that these code elements aren’t erroneously preserved when no root element uses them. There are two methods you can use to change how the Unity linker processes code elements:
The [Preserve]
attribute is useful for situations when an API is always needed. Other attributes can be useful for more general preservations. For example, you can preserve all types that implement a particular interface by annotating the interface with the [RequireImplementorsAttribute]
.
To annotate specific coding patterns, use one or more of the following attributes:
RequireImplementorsAttribute
: Marks all types that implement this interface as dependencies.RequireDerivedAttribute
: Marks all types that derive from this type as dependencies.RequiredInterfaceAttribute
: Marks interface implementations on types as dependencies.RequiredMemberAttribute
: Marks all members of a type as dependencies.RequireAttributeUsagesAttribute
: Marks custom attributes as dependencies.You can combine these attributes in various ways to more precisely control how the Unity linker preserves your code.
The [AlwaysLinkAssembly]
attribute forces the Unity linker to search an assembly regardless of whether or not the assembly is referenced by another assembly that is included in the build. You can only apply the attribute to an assembly.
The attribute doesn’t directly preserve code within the assembly. Instead, this attribute instructs the Unity linker to apply the root marking rules to the assembly. If no code elements match the root marking rules for the assembly, the Unity linker still removes the assembly from the build.
Use this attribute on precompiled or package assemblies that contain one or more methods with the [RuntimeInitializeOnLoadMethod]
attribute, but which might not contain types used directly or indirectly in any scenesA Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
See in Glossary in a project.
If an assembly defines [assembly: AlwaysLinkAssembly]
and is also referenced by another assembly included in the build, the attribute has no effect on the output.
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.