Unity'de yeni bir ekrana başlarken cevaplanması gereken ilk soru şu: uGUI/Canvas mı, UI Toolkit mi? Bu yazıda iki sistemi ekran türü, ekip alışkanlığı ve editör aracı yazma ihtiyacı üzerinden karşılaştırıyoruz; sonunda "şu durumda şunu seç" diyebileceğin bir karar listesi var. Amaç bir kazanan ilan etmek değil, hangi ekranın hangi sistemde daha az direnç gösterdiğini netleştirmek.
İki sistem, iki zihinsel model
uGUI'de her arayüz öğesi bir GameObject'tir. Buton bir GameObject, üzerindeki yazı çoğu zaman ayrı bir GameObject, yerleşim RectTransform'un anchor ve pivot değerleriyle kurulur. Prefab varyantları, Inspector'dan sürükleyip bıraktığın referanslar, Animator klipleri; hepsi Unity'nin geri kalanıyla aynı dille konuşur.
UI Toolkit farklı bir yerden gelir. Yapıyı UXML ağacında tanımlarsın, görünümü USS dosyalarında yazarsın, yerleşim flexbox mantığıyla çalışır. Elementler GameObject değildir; Hierarchy penceresinde tek bir UIDocument görürsün, ağacın kendisi orada görünmez. Kod tarafında referansları isimle veya tiple sorgularsın. Unity'nin uGUI'den UI Toolkit'e geçiş kılavuzu iki sistemin çizim sırası konusunda benzer davrandığını söylüyor: ağaçta daha altta olan üstte çizilir. Benzerlik büyük ölçüde orada bitiyor.
Pratikte fark şuna iniyor: uGUI'de bir ekranı fareyle kurarsın, UI Toolkit'te bir ekranı yazarak kurarsın. UI Builder bu farkı yumuşatır ama tamamen ortadan kaldırmaz.
Unity'nin kendi tavsiyesi neyi işaret ediyor
Unity'nin UI sistemleri karşılaştırma sayfası, geniş bir çözünürlük yelpazesinde çalışan ekran üstü (screen overlay) arayüzler ve arayüz miktarı yüksek projeler için UI Toolkit'i uGUI'ye alternatif olarak değerlendirmeyi öneriyor. Bu, "her şeyi taşı" demek değil. Tavsiyenin dili bile koşullu: belirli iş yükleri için alternatif.
Aynı geçiş kılavuzunda, iki sistemin dağınık biçimde karıştırılmasının bütünlüklü hisseden bir arayüz üretmeyi zorlaştırdığı da yazıyor. Bu uyarıyı ciddiye almak, seçimi ekran ekran değil, ekran kümesi kümesi yapmak anlamına geliyor.
Ekran türüne göre direnç haritası
Dünyaya değen HUD öğeleri: Canvas daha az direnç gösteriyor
Bir kulenin üstünde duran menzil göstergesi, düşmanın başındaki can barı, hasar sayısı, sahne içindeki tıklanabilir işaretçi. Bunların hepsi kamera uzayıyla, sıralama katmanlarıyla, particle ve shader'larla iç içe geçer. World space Canvas bu iş için olgun ve tahmin edilebilir: sorting layer'ı bilirsin, materyalini bilirsin, sahne görünümünde yerini elle sürüklersin. Thornguard: Tower Defense gibi ekranın büyük kısmının oyun alanı olduğu bir yapıda arayüzün oyun nesnelerine yapışması gerekir; bu durumda arayüzü oyun nesnesi olarak tutmak en kısa yol.
Uzun listeler, ayarlar, veri ağırlıklı ekranlar: UI Toolkit rahat
Ayar menüsü, dil listesi, seviye seçimi, envanter, tablo görünümü. Bunlar tekrar eden satırlardan oluşur ve içerik uzunluğuna göre büyür. Flexbox burada RectTransform'dan daha az kavga çıkarır: yazı uzayınca satır büyür, cihazın güvenli alanı değişince padding tek yerden ayarlanır, tema değişikliği USS dosyasında bir satırdır. ListView öğeleri geri dönüştürdüğü için yüzlerce satırlık listede yüzlerce GameObject üretmezsin.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class LevelListScreen : MonoBehaviour
{
[SerializeField] private UIDocument document;
private readonly List<string> levels = new List<string> { "1-1", "1-2", "1-3" };
private void OnEnable()
{
VisualElement root = document.rootVisualElement;
ListView list = root.Q<ListView>("level-list");
list.fixedItemHeight = 48f;
list.makeItem = () => new Label();
list.bindItem = (element, i) => ((Label)element).text = levels[i];
list.itemsSource = levels;
Button resume = root.Q<Button>("resume-button");
if (resume != null)
{
resume.clicked += () => Time.timeScale = 1f;
}
}
}
El yapımı, milimetrik yerleşimler: duruma bağlı
Kart yerleşimi bu kategorinin tipik örneği. Kartların açılı dizilmesi, üst üste binmesi, sürüklenirken ölçek değiştirmesi gibi düzenler ne flexbox'ın ne de anchor sisteminin doğal işi; ikisinde de bir miktar elle konumlandırma kodu yazarsın. Bizim Kart Üçlüsü tarafında öğrendiğimiz şey, bu tür ekranlarda asıl kısıtın sistem değil okunabilirlik olduğu; bunu kart arayüzü okunabilirliği yazısında ayrıntılandırmıştık. Sistem seçimi burada, düzeni hangi dilde ifade etmenin daha kolay olduğuna iner.
Animasyon ağırlıklı geçişler: Canvas'ın ekosistemi hazır
Ekran açılış animasyonları, zincirleme geçişler, Timeline ile senkron sahneler. Canvas tarafında Animator, mevcut tween kütüphaneleri ve alıştığın eğri editörü doğrudan çalışır. UI Toolkit'te USS geçişleri ve kod tabanlı animasyon işi görür ama iş akışı görsel değildir; animasyonu tasarımcının değil programcının yazması gerekir. Ekipte arayüz animasyonunu tasarımcı yapıyorsa bu, teknik değil organizasyonel bir maliyettir.
Editör aracı yazacaksan tartışma kısa
Editör penceresi, özel Inspector, içerik doğrulama aracı yazacaksan UI Toolkit'i seçmemek için pek sebep yok. IMGUI'de her karede yeniden çizen kod yazmak yerine ağacı bir kez kurar, veriyi bağlar, geri kalanını sisteme bırakırsın. Üstelik burada öğrendiğin UXML/USS bilgisi oyun içi arayüze de taşınır: ekip flexbox'ı ve seçicileri bir kez öğrenir, iki yerde kullanır.
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
public class CardBalanceWindow : EditorWindow
{
[MenuItem("Tools/Kart Dengesi")]
private static void Open()
{
GetWindow<CardBalanceWindow>("Kart Dengesi");
}
private void CreateGUI()
{
var search = new ToolbarSearchField();
var list = new ListView { fixedItemHeight = 22f };
rootVisualElement.Add(search);
rootVisualElement.Add(list);
}
}
Bu, sistem seçiminde çoğu zaman gözden kaçan bir kaldıraç: editör aracı ihtiyacı olan bir ekip UI Toolkit'i zaten öğrenmek zorunda kalır. Öğrenme maliyeti bir kez ödendiğinde oyun içi arayüzde de UI Toolkit'e geçmenin fiyatı düşer. Paylaşılan araçların nereye kadar taşınabildiğini iki oyun bir kod tabanı yazısında anlatmıştık; arayüz katmanı o sınırın tam üstünde duruyor.
Ekip alışkanlığının görünmeyen maliyeti
UI Toolkit'in en sinsi tarafı referans yönetimi. uGUI'de bir butonu Inspector'dan sürükler bırakırsın; referans kopmuşsa Unity uyarır. UI Toolkit'te elementi isimle sorgularsın ve isim yanlışsa derleyici susar, hata çalışma zamanında bir NullReferenceException olarak gelir. Basit bir alışkanlık bu riski büyük ölçüde kapatıyor: isimleri sabit olarak tek yerde topla ve ekran açılırken doğrula.
internal static class UiNames
{
public const string ResumeButton = "resume-button";
public const string LevelList = "level-list";
}
İkinci maliyet kalabalık: UI Builder'da yapılan bir değişiklik UXML dosyasında metin farkı üretir, bu da kod incelemesini kolaylaştırır. Buna karşılık prefab tabanlı Canvas ekranlarında sahne ve prefab dosyalarındaki fark okunması zor olabilir. Sürüm kontrolünde arayüz değişikliğini gerçekten inceleyen bir ekipseniz bu, UI Toolkit lehine somut bir puan.
Karıştırmak mümkün ama bedava değil
İki sistem aynı projede yaşayabilir; biz de öyle yapıyoruz. Ama sınırı ekran düzeyinde çizmek gerekiyor: aynı ekranın içinde iki sistem karışmasın. Karıştığında ortaya çıkan tipik sorunlar girdi ve odak yönetiminde toplanıyor. Canvas'ın raycast'i ile UI Toolkit'in olay yakalaması ayrı çalışır; üst üste binen panellerde tıklamanın hangi katmana gittiğini test etmen gerekir. Gamepad veya klavye odağı kullanıyorsan iki ayrı odak sistemini elle köprülemek zorunda kalırsın.
Performans tarafında da ölçümü ayrı yapmak gerekiyor: iki sistem profiler'da farklı başlıklar altında görünür, bu yüzden "arayüz pahalı" demeden önce hangi arayüzün pahalı olduğunu ayırmak lazım. Profiler'ı bu gözle okumaya dair notlarımız mobilde kare süresi yazısında duruyor.
Karar listesi: şu durumda şunu seç
- Editör penceresi veya özel Inspector yazıyorsan: UI Toolkit.
- Arayüz sahnedeki bir nesneye yapışıyorsa (can barı, kule menüsü, dünya işaretçisi): Canvas.
- Ekran uzun liste, tablo, ayar veya metin ağırlıklıysa ve çok farklı çözünürlükte çalışacaksa: UI Toolkit.
- Arayüz shader, particle ve sıralama katmanlarıyla iç içe geçiyorsa: Canvas.
- Arayüz animasyonlarını tasarımcı yapıyorsa: Canvas.
- Ekipte kimse flexbox/USS bilmiyorsa ve teslim iki hafta içindeyse: Canvas. Öğrenmeyi teslimin ortasına koyma.
- Çalışan büyük bir Canvas ekranı varsa: dokunma. Taşımanın karşılığında somut bir kazanç yoksa taşıma bir maliyet kalemidir.
- Sıfırdan bir meta ekran kümesi kuruyorsan (menü, ayar, mağaza): UI Toolkit'i seç, ama önce en karmaşık ekranı prototiple.
Bizim şu anki kuralımız
Editör tarafı tamamen UI Toolkit. Oyun dünyasına değen her şey Canvas. Aradaki meta ekranlarda kararı ekranın kendisi veriyor: içerik veriden geliyorsa ve satır sayısı değişkense UI Toolkit, düzen elle kurulmuş ve animasyon yüklüyse Canvas.
Seçimden emin olamadığımızda sorduğumuz soru teknik değil: bu ekranı altı ay sonra kim açıp değiştirecek? Cevap "bir programcı" ise UI Toolkit'in yazı ağırlıklı iş akışı sorun çıkarmıyor. Cevap "sahnede sürükleyerek düzenleyecek biri" ise Canvas'ta kalmak daha az sürtünme üretiyor. Özellik kesme kararlarında olduğu gibi burada da maliyet ilk günde değil, altıncı ayda ortaya çıkıyor.
Yorumlar
İlk yorumu siz yapın.

