
Artikel ini membahas optimalisasi elemen-UI proyek yang dibuat di Unity. Berdasarkan informasi dari dokumentasi resmi dan pengalaman pribadi, saya mencoba menjelaskan dengan jelas prinsip-prinsip pengoperasian elemen UI. Juga di sini Anda akan menemukan tips praktis yang akan membantu meningkatkan kinerja proyek Anda sehubungan dengan antarmuka pengguna.
Terminologi
Elemen UI adalah semua elemen di Unity yang terkait dengan pembuatan antarmuka pengguna. Ini termasuk, misalnya: tombol, teks, gambar, menu drop-down, dll.
Kanvas (kanvas) - elemen dasar dari UI, yang merupakan wadah untuk sisa elemen.
Mesh - satu set parameter yang menggambarkan model 3D.
Quad adalah mesh yang merupakan quadrangle.
Batching - menggabungkan objek mesh menjadi satu mesh besar untuk rendering lebih cepat.
Draw-call - perintah untuk menggambar dari mesin ke API grafik (misalnya, OpenGL atau Direct3D).
Antrian transparan - antrian untuk merender objek transparan.
Alpha blending (Alpha blending) - sebuah algoritma untuk pencampuran piksel pada saluran alpha untuk mendapatkan gambar dengan transparansi.
Atlas adalah jenis sumber daya yang menggabungkan beberapa tekstur menjadi satu.
Pendahuluan
Dalam optimasi UI, tidak ada aturan universal yang berfungsi dalam situasi apa pun. Semuanya bermuara pada menemukan keseimbangan antara biaya batching dan jumlah panggilan draw. Empat masalah utama dapat dibedakan:
- Memuat GPU terlalu tinggi (kelebihan beban di render);
- terlalu banyak beban CPU saat membangun kembali kanvas;
- terlalu banyak elemen yang berubah yang mengarah pada pembangunan kembali kanvas;
- Beban CPU terlalu besar untuk pembuatan mesh (biasanya terkait dengan teks).
Rendering UI kesatuan
Elemen dasar dari antarmuka pengguna Unity adalah kanvas. Ia bertanggung jawab untuk membuat, menyortir, dan merender elemen-elemen antarmuka anak. Semua elemen UI harus anak-anak dari kanvas apa pun, jika tidak mereka tidak akan ditampilkan dalam permainan.

Rendering terjadi dari objek terjauh ke terjauh dari kamera (back-to-front) dalam antrian Transparan dengan alpha blending.
Secara terpisah, harus dicatat bahwa transparansi elemen UI TIDAK mempengaruhi kinerja. Bahkan jika elemen seluruhnya terdiri dari piksel "buram", itu masih akan dirender menggunakan alpha blending.
Penting juga untuk dipahami bahwa saat merender, semua piksel dari semua elemen aktif diproses. Itu tidak tergantung pada apakah mereka terlihat, diblokir oleh benda lain atau bahkan sepenuhnya transparan.
Mendesain ulang antarmuka pengguna
Mendesain ulang antarmuka pengguna adalah proses multi-langkah, termasuk membangun jerat dari setiap elemen UI, dan mencoba untuk menambal jerat ini untuk meminimalkan jumlah panggilan draw .
Pembangunan kembali berlangsung dalam empat tahap:
- Struktur elemen dianalisis.
- Jerat semua elemen aktif, termasuk elemen dengan nol transparansi, dibangun kembali.
- Membangun kembali material untuk mesh elemen meshing.
- Semua elemen digambar sesuai urutannya.
Kanvas yang dibangun kembali di-cache dan digunakan kembali sampai salah satu elemen di kanvas ditandai sebagai diubah.
Objek kotor ditandai yang telah diaktifkan atau dinonaktifkan; yang telah mengubah material, posisi, skala, rotasi; nilai teks dari komponen teks telah berubah; penugasan kembali orang tua, dll.
Dalam kasus ini, pembangunan kembali kanvas mengandung setidaknya satu elemen yang diubah. Benar, ini hanya berlaku untuk kanvas tempat elemen berada. Artinya, perubahan elemen dalam kanvas anak tidak memengaruhi elemen induk.
Semakin banyak elemen dalam kanvas, semakin besar biaya menganalisis dan menyortir objek.
Meshing
Menggabungkan jerat, atau batching, membantu mengurangi beban pada GPU dengan mengurangi jumlah panggilan draw. Selama proses batching, jerat diurutkan berdasarkan kedalaman dan diperiksa untuk tumpang tindih. Ketika melewati dari elemen yang jauh ke elemen dekat (atau dari elemen atas ke yang lebih rendah dalam hierarki), objek dengan bahan atau tekstur yang sama digabungkan menjadi satu jala di dalam kanvas yang sama. Untuk ini, tidak boleh ada benda dengan bahan lain di antara mereka. Selain itu, benda dengan bahan lain tidak boleh tumpang tindih dengan benda yang dipanggang secara keseluruhan. Operasi batching adalah multi-threaded, kinerjanya sangat bervariasi tergantung pada jumlah core dalam prosesor.
Teks mungkin bergetar dengan teks lain jika mereka memiliki font yang sama. Tidak masalah jika pengaturan dan gaya font sama atau berbeda. Jika font berbeda, maka teks tidak akan bergulir.
Juga harus diingat bahwa teks dapat tumpang tindih objek dengan wadah keseluruhan, dan tumpang tindih seperti itu dapat dengan mudah dilewati.

Pertimbangkan sebuah contoh. Ada tiga objek A, B, dan C yang diatur dalam hierarki dengan cara ini:


Pada gambar di sebelah kiri, objek A dan C akan digabung, karena memiliki bahan yang sama dan tidak bersinggungan dengan objek B. Pada gambar di sebelah kanan, objek A dan C tidak akan digabungkan, karena ada persimpangan dengan objek B.
Tips Optimalisasi UI Umum
Sebelum Anda memulai pengoptimalan, Anda disarankan menggunakan UI profil. Ini akan membantu mengidentifikasi hambatan yang menyebabkan hilangnya kinerja (jika ada). Untuk membuat profil, ada banyak alat, baik bawaan untuk Unity (Unity Profiler), dan yang pihak ketiga. Tetapi kami tidak akan membahas masalah profil UI dalam artikel ini.
Berikut adalah beberapa saran untuk mengoptimalkan UI Anda di Unity:
- Matikan benda yang tak terlihat. Jika sebuah elemen tumpang tindih oleh elemen buram, maka Anda harus menonaktifkan GameObject atau induk GameObject dari elemen yang tumpang tindih. Pada saat yang sama, elemen antarmuka dengan alpha yang diatur ke 0 akan tetap digambar. Untuk objek seperti itu, Anda harus mengaktifkan Cull Transparent Mesh di komponen Canvas Renderer atau cukup menonaktifkan objek yang tidak terlihat.

- Nonaktifkan objek dunia yang disembunyikan oleh antarmuka buram. Jika antarmuka tidak mencakup seluruh dunia, Anda dapat menyimpannya di Tekstur Render, dan mematikan kamera dunia.
- Minimalkan jumlah piksel untuk menggambar. Gabungkan sebanyak mungkin gambar menjadi satu. Sebagai contoh, masuk akal untuk membuat tombol sebagai sprite tunggal, daripada memisahkan layer dengan latar belakang, goresan, badan tombol, dll. Ini akan mengurangi fleksibilitas bekerja dengan elemen-elemen tersebut dan dapat menyebabkan penyumbatan sumber daya, sehingga kompromi harus dicari.

- Hindari elemen kosong yang hanya berfungsi untuk mengatur struktur (jangan gunakan elemen sebagai nama "folder" dalam hierarki dokumen).
- Hindari menyilangkan benda yang tidak bisa dipanggang satu sama lain. Jika memungkinkan, yang terbaik adalah mengubah posisi dalam hierarki, ukuran wadah, atau posisi elemen yang tumpang tindih dan non-caking.
- Gunakan kanvas terpisah atau bersarang untuk elemen dinamis. Jadi Anda meminimalkan biaya penyortiran dan membangun kembali struktur kanvas yang mengandung sejumlah besar elemen. Kanvas bersarang lebih nyaman, karena mewarisi pengaturan kanvas induk. Pada saat yang sama, ketika mengubah kanvas induk, semua yang bersarang juga akan dibangun kembali. Ini cukup jarang, tetapi itu terjadi (misalnya, ketika mengubah resolusi layar). Perlu diingat bahwa objek dari kanvas yang berbeda atau kanvas bersarang TIDAK dipanggang untuk rendering bersama. Dianjurkan untuk membagi kanvas sesuai dengan keteraturan memperbarui elemen. Elemen statis perlu ditempatkan di kanvas yang terpisah, maka mereka akan digambar hanya sekali. Jika ada elemen yang terus berubah, maka lebih baik menggabungkannya di kanvas lain, karena mereka masih akan saling membangun kembali. Mengubah objek juga dapat dibagi menjadi beberapa kanvas berdasarkan kecepatan refresh. Misalnya, elemen yang diperbarui setiap bingkai ditempatkan di satu kanvas, dan elemen diperbarui lebih jarang di yang lain.
- Menonaktifkan Pixel Perfect akan secara signifikan meningkatkan produktivitas. Ini terutama berlaku untuk objek yang terus diperbarui dengan sejumlah besar elemen (misalnya, menggulir inventaris).

Kanvas itu

Kanvas bersarang - Jika Anda perlu menonaktifkan kanvas, jangan nonaktifkan objek yang memuatnya (melalui fungsi SetActive ). Lain kali Anda mengaktifkan elemen kanvas ini ditandai sebagai diubah, dan semua elemen dibangun kembali. Lebih baik mematikan komponen kanvas itu sendiri, maka seluruh struktur dan data yang dipanggang tidak akan berubah dan saat berikutnya Anda menghidupkan komponen kanvas, mereka baru saja mulai menggambar.

- Untuk kanvas dengan Ruang Layar - Kamera atau Ruang Dunia dipilih dalam parameter Mode Render , selalu instal kamera. Jika Anda tidak menginstalnya, maka sistem antarmuka pengguna di setiap frame akan mencari melalui Object.FindObjectWithTag untuk menemukan Camera.main , dan ini akan mempengaruhi kinerja.
- Agar tidak membuat beberapa tekstur yang identik, Anda dapat membuatnya dalam nuansa abu-abu dan โmengecatnyaโ melalui komponen Image dengan memilih warna yang diinginkan.

- Biarkan bendera Target Raycast hanya pada item yang membutuhkan acara masukan, dan hapus sisanya. Secara default, target Raycast diaktifkan pada banyak elemen (Gambar, Teks, dll.). Ini menyulitkan dan memperlambat kerja komponen Raycaster , yang menangani input event di Unity UI. Saat mengklik atau merekam, ia akan menelusuri seluruh hierarki elemen dan mencari semua komponen grafis dengan set bendera Target Raycast, lalu memeriksanya untuk kemungkinan peristiwa input dan, setelah melewati pemeriksaan dengan sukses, menambahkannya ke daftar klik. Setelah itu, daftar hit diurutkan berdasarkan kedalaman, objek di luar layar dibuang. Sebagai hasilnya, ia memberikan daftar hit terakhir.
Di Unity UI, banyak komponen (Gambar, Teks, dll.) Memiliki bendera Target Raycast .

Target Raycast pada komponen gambar.

TextMeshPro menyembunyikannya di tab Pengaturan Ekstra .

Untuk TextMeshPro, Anda dapat mengatur pengaturan Target Raycast default di Pengaturan Player -> TextMest Pro -> Pengaturan -> Aktifkan Target Raycast .
Elemen diuji ketika:
- Target Raycast diaktifkan
- elemen itu sendiri dihidupkan dan diaktifkan;
- titik penyisipan berada di persimpangan dengan RectTransform.
Masuk akal juga untuk menghapus bendera Target Raycast dari anak-anak jika objek root sudah memilikinya dan benar-benar tumpang tindih anak-anak dengan geometri. Misalnya, tombol UI Unity standar.

Gambar sepenuhnya tumpang tindih teks dengan bentuknya, dalam hal ini, Anda dapat menghapus Target Raycast dari komponen teks.

Jika semua elemen kanvas tidak menunggu peristiwa input, maka Anda dapat menghapus komponen Graphic Raycaster dari kanvas / kanvas bersarang.
Bekerja dengan teks dan pengoptimalannya
Teks dalam antarmuka Unity terdiri dari kisi-kisi di mana setiap simbol dibuat quad-nya sendiri. Mesh dibangun kembali setiap kali nilai teks berubah. Rebuild juga terjadi jika komponen teks atau induknya dimatikan dan dihidupkan lagi.
Secara default, font di Unity ditambahkan sebagai dinamis. Untuk setiap font dinamis yang digunakan dalam komponen teks di atas panggung, sebuah atlas dibuat. Hanya karakter yang digunakan yang termasuk dalam atlas ini. Misalnya, jika bidang teks berisi teks "Teks Baru", maka atlas yang dibuat untuknya akan berisi karakter "N", "e", "w", "T", "x" dan "t". Untuk setiap karakter yang berbeda dalam ukuran atau gaya, representasi akan dibuat di atlas.

Teks di atas panggung

Atlas font
Jika selama pelaksanaan program konten dari komponen teks berubah dan ada karakter yang tidak ada di atlas, seluruh atlas akan dibangun kembali. Jika ada ruang kosong di tekstur atlas, maka simbol yang diperlukan akan ditambahkan di sana. Pada saat yang sama, karakter yang sedang tidak digunakan tidak akan dihapus. Jika tidak ada cukup ruang di atlas untuk karakter baru, ukurannya akan digandakan dan diisi lagi berdasarkan karakter yang digunakan dalam komponen teks aktif.
Jika jumlah karakter yang ditentukan secara ketat diatur untuk proyek, misalnya, hanya alfabet Latin, maka layak menggunakan font statis yang disimpan secara permanen dalam memori. Jika proyek Anda memungkinkan sejumlah besar karakter, lebih baik memikirkan font dinamis.
Anda juga dapat meningkatkan kinerja dengan mengganti komponen teks dengan sprite. Misalnya, angka-angka yang muncul dalam permainan (skor) dapat dibuat menggunakan sprite dari satu atlas yang hanya berisi sekumpulan karakter yang diperlukan. Dalam hal ini, tidak akan ada biaya untuk membangun kembali kanvas dan atlas font.
Penggunaan font fallback, terdaftar di bidang Nama Font di pengaturan font, meningkatkan memori yang digunakan. Ini terutama terlihat dalam font piktografik.
Tidak disarankan untuk menggunakan Paling Cocok , karena opsi ini menyebabkan meluapnya atlas dengan cepat dan menyebabkan restrukturisasi.
Paling cocok mengabaikan pengaturan ukuran font dan mencoba menyesuaikan teks ke dalam persegi panjang garis besar komponen teks.
Sekarang beberapa kata tentang TextMeshPro (TMP) , pengganti populer untuk komponen teks Unity standar. TextMeshPro juga membangun kembali kisi-kisinya setiap kali nilai teks berubah. Namun, teks TMP tidak menggunakan font dinamis. Untuk itu, atlas font dibuat terlebih dahulu, yang mencakup semua karakter yang diperlukan. Jika untuk beberapa teks di tempat kejadian tidak ada karakter dalam font yang ditetapkan untuk komponennya, maka TMP mulai mencari dalam font cadangan. Jika tidak ada apa-apa di sana, maka TMP akan mencoba menemukan karakter ini di semua font yang diunduh.
Best Fit in TMP tidak menciptakan masalah seperti komponen teks biasa, sehingga dapat digunakan.
Sejumlah besar font dengan pelokalan berbeda atau font font besar dapat memakan banyak memori. Oleh karena itu, lebih baik menggunakan preload hanya font yang diperlukan untuk pelokalan tertentu.
World Space merekomendasikan penggunaan TextMeshPro sebagai ganti TextMeshProUGUI .
TextMeshProUGUI digunakan dalam kanvas.
Sprite Atlases
Atlas Sprite adalah jenis sumber daya yang menggabungkan beberapa tekstur menjadi satu. Mereka memungkinkan Anda untuk mengurangi jumlah undian ( menarik panggilan ) dan meningkatkan produktivitas.
Penciptaan Atlas.
Buat sebuah atlas: Aset> Buat> Sprite Atlas .
Pilih atlas dan letakkan sprite yang diperlukan di Objects for Packing .

Klik Pack Preview untuk mempratinjau atlas.

Ingatlah bahwa meskipun satu atau lebih sprite dari atlas digunakan di tempat kejadian, atlas akan tetap dimuat secara keseluruhan. Oleh karena itu, tidak masuk akal untuk mencoba menanamkan semua gambar dalam satu atlas raksasa, yang pada perangkat dengan RAM kecil dapat mengambil bagian yang nyata. Lebih baik membobol beberapa atlas yang lebih kecil, misalnya atlas antarmuka pengguna menu game dan atlas antarmuka mode permainan.
Hindari ruang kosong besar di atlas, agar tidak menempati ruang memori berlebih. Untuk melakukan ini, Anda dapat mengubah ukuran atlas atau menambahkan gambar tambahan untuk mengisi ruang kosong sebanyak mungkin.


Untuk gambar yang tidak ada di atlas, Anda harus memilih pengaturan yang benar.
Untuk setiap format kompresi, ada persyaratan yang akan digunakan secara efisien. Persyaratan gambar yang paling umum:
- lebar dan tinggi harus merupakan kelipatan dari kekuatan dua;
- lebar dan tinggi harus kelipatan 4;
- kedua paragraf sebelumnya bersama-sama.
Jika tidak, tekstur tidak akan dikompresi dan biaya memori perangkat tambahan akan terjadi.
Saat memilih format kompresi, Unity akan memberi tahu Anda jika ada persyaratan untuk format yang dipilih tidak terpenuhi.

Juga jangan lupa bahwa formatnya berbeda dari perangkat target. Untuk informasi dan rekomendasi lebih lanjut tentang format, lihat dokumentasi resmi :
Ringkas metode pengoptimalan
- Nonaktifkan objek yang tidak terlihat dan transparan
- Minimalkan jumlah item
- Hindari menyilangkan benda yang tidak bisa dipanggang satu sama lain
- Bagikan item berdasarkan kanvas berdasarkan kecepatan refresh
- Untuk kanvas dengan elemen yang sering diperbarui, nonaktifkan Pixel Perfect
- Nonaktifkan Target Raycast pada item yang tidak dapat diklik
- Hapus komponen Graphic Raycaster pada kanvas yang semua elemennya tidak dapat diklik
- Untuk komponen teks biasa, jangan gunakan Paling Cocok
- Untuk TextMeshPro In World Space, gunakan TextMeshPro sebagai ganti TextMeshProUGUI. TextMeshProUGUI digunakan di kanvas
- Atur kamera dalam pengaturan kanvas, jika perlu
- Nonaktifkan kanvas dengan menonaktifkan komponen kanvas
- Gunakan sprite grayscale dan mewarnai pengaturan komponen gambar
- Gunakan atlas sprite
- Gunakan ukuran dan format kompresi yang benar untuk tekstur yang tidak ada di atlas
Sumber:
Informasi Optimalisasi Unity UI Komprehensif
Sumber resmi lain tentang topik ini berisi informasi dalam bentuk yang lebih ringkas.
Kertas Putih Atlas
Informasi Tambahan tentang Format Kompresi Tekstur