Selama proses build, Unity menghapus kode yang tidak dapat digunakan atau tidak terjangkau melalui proses yang disebut pengupasan kode yang dikelola, yang secara signifikan dapat menurunkan ukuran akhir aplikasi Anda. Garis kode terkelola menghapus kode dari rakitan yang dikelola, termasuk rak yang dibangun dari C # scriptsSepotong kode yang memungkinkan Anda untuk membuat Komponen Anda sendiri, memicu peristiwa permainan, memodifikasi sifat komponen dari waktu ke waktu dan menanggapi input pengguna dengan cara apa pun yang Anda sukai. More info
Lihat di Glossary dalam proyek Anda, perakitan yang merupakan bagian dari paket dan plugin, dan perakitan di .NET Framework.
Unity menggunakan alat yang disebut Unity linker untuk melakukan analisis statis dari kode di rakitan proyek Anda. Analisis statis mengidentifikasi setiap kelas, bagian kelas, fungsi, atau bagian fungsi yang tidak dapat dicapai selama eksekusi. Analisis ini hanya mencakup kode yang ada pada waktu build karena kode yang dihasilkan runtime tidak ada ketika Unity melakukan analisis statis.
Anda dapat mengkonfigurasi tingkat pengupasan kode Unity melakukan untuk proyek Anda menggunakan pengaturan Managed Stripping Level. Untuk mencegah Unity menghapus bagian spesifik dari kode Anda, gunakan anotasi untuk menunjukkan bagian mana dari basis kode Anda, linker Unity harus melestarikan. Untuk informasi lebih lanjut, lihat WordPress.org.
Properti Managed Stripping Level menentukan seperangkat aturan yang disatukan linker berikut ketika menganalisis dan menggariskan kode aplikasi Anda. Ketika Anda meningkatkan pengaturan dari Minimal ke High, aturan memungkinkan penghubung untuk mencari melalui lebih banyak perakitan untuk kode yang tidak terjangkau. Linker Unity menghapus lebih banyak kode pada pengaturan yang lebih tinggi yang mengurangi ukuran akhir dari build Anda, meskipun pencarian yang diperluas berarti bahwa setiap build membutuhkan lebih lama untuk menghasilkan.
Untuk mengubah properti Managed Stripping Level:
Property: | Function: |
---|---|
Disabled | Unity tidak menghapus kode. Pengaturan ini hanya terlihat dan merupakan pengaturan default jika Anda menggunakan backend skrip Mono. |
Minimal | Satuan pencarian hanya UnityEngine dan . Perpustakaan kelas NET untuk kode yang tidak digunakan. Unity tidak menghapus kode user-written. Pengaturan ini adalah kemungkinan besar untuk menyebabkan perilaku runtime yang tidak terduga. Pengaturan ini berguna untuk proyek di mana kegunaan adalah prioritas yang lebih tinggi daripada membangun ukuran. Ini adalah pengaturan default jika Anda menggunakan backend IL2CPP scripting. |
Low | Satuan mencari beberapa rakitan pengguna dan semua UnityEngine dan. Perpustakaan kelas NET untuk kode yang tidak digunakan. Pengaturan ini berlaku seperangkat aturan yang menghapus beberapa kode yang tidak digunakan tetapi meminimalkan kemungkinan konsekuensi yang tidak diinginkan, seperti perubahan perilaku kode runtime yang menggunakan refleksi. |
Medium | Satuan sebagian mencari semua rakitan untuk menemukan kode yang tidak terjangkau. Pengaturan ini berlaku satu set aturan yang strip lebih banyak jenis pola kode untuk mengurangi ukuran build. Meskipun Unity tidak memupuk semua kode yang tidak terjangkau, pengaturan ini meningkatkan risiko perubahan perilaku yang tidak diinginkan atau tak terduga. |
High | Unity melakukan pencarian yang luas dari semua rakitan untuk menemukan kode yang tidak terjangkau. Pada pengaturan ini, Unity memprioritaskan pengurangan ukuran lebih dari stabilitas kode dan menghapus sebanyak mungkin kode. Pencarian ini dapat memakan waktu lebih lama daripada untuk tingkat pengupasan yang lebih rendah. Gunakan pengaturan ini hanya untuk proyek di mana ukuran build kompak sangat penting. Uji aplikasi Anda secara menyeluruh dan gunakan atribut [Preserve] dan link.xml untuk memastikan bahwa linker Unity tidak strip kode vital. |
Anda dapat menggunakan anotasi untuk mencegah tautan Unity dari pengupasan bagian spesifik kode Anda. Ini membantu jika aplikasi Anda menghasilkan kode runtime yang tidak ada ketika Unity melakukan analisis statis; misalnya, melalui reflection. Annotations baik memberikan panduan umum untuk linker Unity tentang pola kode mana itu tidak harus strip, atau instruksi untuk tidak strip bagian tertentu yang ditentukan dari kode.
Ada dua pendekatan yang luas yang dapat Anda gunakan untuk mengumumkan kode Anda untuk menjaganya dari proses pengupasan kode yang dikelola:
Masing-masing teknik ini menyediakan lebih banyak kontrol atas jumlah kode yang disatukan strip linker pada tingkat pengupasan yang lebih tinggi dan mengurangi kemungkinan kode vital dilucuti. Anotasi sangat berguna ketika referensi kode Anda melalui refleksi, karena tautan Unity tidak dapat selalu mendeteksi penggunaan refleksi.
Mempertahankan kode yang menggunakan refleksi atau menghasilkan kode lain pada runtime untuk secara signifikan mengurangi kemungkinan perilaku tak terduga ketika aplikasi Anda dieksekusi. Sebagai contoh pola refleksi yang dapat mengenali tautan Unity, lihat Unity Intermediet Bahasa Linker refleksi paket tes.
Anotasi akar memaksa penghubung Unity untuk mengobati elemen kode sebagai akar, yang tidak dilucuti dalam proses pengupasan kode. Ada dua jenis anotasi akar yang dapat Anda gunakan, tergantung apakah Anda perlu melestarikan jenis individu dengan konstruktor atau rakitan mereka:
Gunakan atribut Preserve untuk secara individual termasuk bagian spesifik dari kode Anda dari analisis statis Unity linker. Untuk mengumumkan sepotong kode dengan atribut ini, tambahkan [Preserve]
segera sebelum bagian pertama dari kode yang ingin Anda simpan. Daftar berikut menjelaskan entitas apa yang disimpan tautan Unity ketika Anda mengumumkan elemen kode yang berbeda dengan atribut [Preserve]
:
[Preserve]
ke perakitan, letakkan deklarasi atribut di file C # yang disertakan dalam perakitan, sebelum deklarasi namespace.[add]
, dan aksesor [remove]
.Gunakan atribut [Preserve]
ketika Anda ingin melestarikan jenis dan konstruktor default. Jika Anda ingin menyimpan satu atau yang lain tetapi tidak keduanya, gunakan file link.xml.
Anda dapat mendefinisikan atribut [Preserve]
di setiap perakitan dan di ruang nama. Anda dapat menggunakan UnityEngine. Login Kelas PreserveAttribute, menciptakan subkelas UnityEngine. Login Mengamati, atau membuat kelas Anda sendiri. Contoh:
class Foo
{
[Preserve]
public void PreservedMethod(){}
}
Anda dapat menyertakan .xml file link yang berhak.xml dalam proyek Anda untuk melestarikan daftar rakitan atau bagian rakitan tertentu. File link.xml harus ada di folder Assets
atau subdirectory dari folder Assets
dalam proyek Anda dan harus menyertakan tag <linker>
dalam file. Linker Unity memperlakukan perakitan, jenis, atau anggota yang diawetkan dalam file link.xml sebagai jenis akar.
Anda dapat menggunakan sejumlah file link.xml di proyek Anda. Akibatnya, Anda dapat menyediakan deklarasi pelestarian terpisah untuk setiap plugin. Anda tidak dapat menyertakan file link.xml dalam paket, tetapi Anda dapat merujuk paket perakitan dari file non-paket.xml.
Contoh berikut menggambarkan cara yang berbeda yang dapat Anda deklarasikan jenis akar rakitan proyek menggunakan file link.xml:
<linker>
<!--Preserve types and members in an assembly-->
<assembly fullname="AssemblyName">
<!--Preserve an entire type-->
<type fullname="AssemblyName.MethodName" preserve="all"/>
<!--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>
</assembly>
</linker>
Contoh berikutnya menunjukkan bagaimana Anda dapat menyatakan seluruh rakitan:
<!--Preserve an entire assembly-->
<assembly fullname="AssemblyName" preserve="all"/>
<!--No "preserve" attribute and no types specified means preserve all-->
<assembly fullname="AssemblyName"/>
<!--Fully qualified assembly name-->
<assembly fullname="AssemblyName, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<type fullname="AssemblyName.Foo" preserve="all"/>
</assembly>
<!--Force an assembly to be processed for roots but don’t explicitly preserve anything in particular. Useful when the assembly isn't referenced.-->
<assembly fullname="AssemblyName" preserve="nothing"/>
Contoh ini menunjukkan cara melestarikan jenis bersarang atau generik:
<!--Examples with generics-->
<type fullname="AssemblyName.G`1">
<!--Preserve a field with generics in the signature-->
<field signature="System.Collections.Generic.List`1<System.Int32> FieldName" />
<field signature="System.Collections.Generic.List`1<T> FieldName" />
<!--Preserve a method with generics in the signature-->
<method signature="System.Void MethodName(System.Collections.Generic.List`1<System.Int32>)" />
<!--Preserve an event with generics in the signature-->
<event signature="System.EventHandler`1<System.EventArgs> EventName" />
</type>
<!--Preserve a nested type-->
<type fullname="AssemblyName.H/Nested" preserve="all"/>
<!--Preserve all fields of a type if the type is used. If the type isn't used, it will be removed-->
<type fullname="AssemblyName.I" preserve="fields" required="0"/>
<!--Preserve all methods of a type if the type is used. If the type isn't used, it will be removed-->
<type fullname="AssemblyName.J" preserve="methods" required="0"/>
<!--Preserve all types in a namespace-->
<type fullname="AssemblyName.SomeNamespace*" />
<!--Preserve all types with a common prefix in their name-->
<type fullname="Prefix*" />
Elemen <assembly>
dari file link.xml memiliki tiga atribut tujuan khusus yang dapat Anda aktifkan untuk kontrol lebih atas annotasi.
ignoreIfMissing
: Gunakan atribut ini jika Anda perlu untuk menyatakan pelestarian untuk perakitan yang tidak ada selama semua pemain membangun.<linker>
<assembly fullname="Foo" ignoreIfMissing="1">
<type name="TypeName"/>
</assembly>
</linker>
ignoreIfUnreferenced:
In some cases, you might want to preserve entities in an assembly only when that assembly is referenced by another assembly. Use this attribute to preserve the entities in an assembly only when at least one type is referenced in an assembly.<linker>
<assembly fullname="Bar" ignoreIfUnreferenced="1">
<type name="TypeName"/>
</assembly>
</linker>
windowsruntime:
ke elemen windowsruntime
dalam file link.xml:<assembly>
element in the link.xml file:<linker>
<assembly fullname="Windows" windowsruntime="true">
<type name="TypeName"/>
</assembly>
</linker>
Anotasi ketergantungan menentukan ketergantungan antara berbagai elemen kode. Anotasi ini berguna untuk menjaga pola kode yang dapat dianalisis secara statis, seperti refleksi. Anotasi ini juga memastikan bahwa elemen kode ini tidak terjaga ketika tidak ada elemen akar menggunakannya. Ada dua metode yang dapat Anda gunakan untuk mengubah bagaimana elemen kode proses tautan Unity:
Atribut [Preserve]
berguna untuk situasi ketika API selalu diperlukan. Atribut lain dapat berguna untuk lebih pelestarian umum. Misalnya, Anda dapat melestarikan semua jenis yang mengimplementasikan antarmuka tertentu dengan mengalokasikan antarmuka dengan Login Login.
Untuk mengalokasikan pola pengkodean tertentu, gunakan satu atau lebih atribut berikut:
Anda dapat menggabungkan atribut ini dengan berbagai cara untuk mengontrol lebih tepat bagaimana tautan Unity melestarikan kode Anda.
Atribut [assembly: UnityEngine.Scripting.AlwaysLinkAssembly]
memaksa penghubung Unity untuk mencari perakitan terlepas dari apakah atau tidak perakitan direferensikan oleh perakitan lain yang disertakan dalam build. Anda dapat menerapkan atribut AlwaysLinkAssembly hanya untuk perakitan.
Atribut tidak langsung melestarikan kode dalam perakitan. Sebagai gantinya, atribut ini menginstruksikan tautan Unity untuk menerapkan aturan penandaan akar ke perakitan. Jika tidak ada elemen kode yang sesuai dengan aturan penandaan akar untuk perakitan, tautan Unity masih menghilangkan perakitan dari build.
Gunakan atribut ini pada rakitan atau paket yang telah ditentukan yang mengandung satu atau lebih metode dengan atribut [RuntimeInitializeOnLoadMethod]
, tetapi yang mungkin tidak mengandung jenis yang digunakan secara langsung atau tidak langsung dalam setiap ScenesAdegan berisi lingkungan dan menu permainan Anda. Pikirkan setiap file Adegan unik sebagai tingkat yang unik. Di setiap Adegan, Anda menempatkan lingkungan, hambatan, dan dekorasi, pada dasarnya merancang dan membangun permainan Anda dalam potongan-potongan. More info
Lihat di Glossary dalam proyek.
Jika perakitan mendefinisikan [assembly: AlwaysLinkAssembly]
dan juga direferensikan oleh perakitan lain termasuk dalam build, atribut tidak memiliki efek pada output.