Unity, oyun geliştiricilerine güçlü bir oyun motoru sunmanın yanı sıra, Editor’ünü özelleştirme ve geliştirme konusunda da büyük bir esneklik tanır. Bu sayede, geliştirme sürecinizi hızlandıracak ve iş akışınızı kolaylaştıracak kendi özel araçlarınızı oluşturabilirsiniz. Bu makalede, Unity Editor scripting’in temel taşlarından biri olan EditorGUILayout.Toggle()
metodunu detaylıca inceleyeceğiz. Bu metodun ne işe yaradığını, nasıl kullanıldığını ve en iyi pratiklerini öğrenerek, Unity Editor’unuzu daha verimli hale getireceksiniz.
EditorGUILayout.Toggle() Nedir ve Neden Kullanılır?
EditorGUILayout.Toggle()
, Unity Editor’da bir boolean (doğru/yanlış) değeri görsel olarak temsil etmek ve değiştirmek için kullanılan bir GUI kontrolüdür. Genellikle özel Inspector’larda (Custom Inspector) veya Editor pencerelerinde (Editor Window) bir ayarı açıp kapatmak, bir özelliği etkinleştirmek veya devre dışı bırakmak gibi durumlar için kullanılır. Bir onay kutusu (checkbox) şeklinde görünür ve kullanıcı tıkladığında durumunu değiştirir.
EditorGUILayout
sınıfı, Editor’da düzenleme kontrolleri oluşturmak için kullanılır ve GUILayout
sınıfının Editor’a özgü bir versiyonudur. En büyük avantajı, elemanların otomatik olarak düzenlenmesi (auto-layout) özelliğidir. Bu sayede, elemanların konumunu ve boyutunu manuel olarak ayarlamak yerine, Unity’nin otomatik yerleşim sistemine güvenebilir, böylece daha az kodla daha düzenli arayüzler oluşturabilirsiniz.
EditorGUILayout Toggle Kullanımı Temelleri
EditorGUILayout.Toggle()
metodunun birkaç farklı imzası bulunur, ancak en yaygın kullanılanları şunlardır:
EditorGUILayout.Toggle(bool value)
: Sadece bir toggle kontrolü oluşturur.EditorGUILayout.Toggle(string label, bool value)
: Bir metin etiketi ile birlikte bir toggle kontrolü oluşturur.EditorGUILayout.Toggle(GUIContent label, bool value)
: Daha gelişmiş etiketleme içinGUIContent
kullanır (örn: tooltip ekleme).
Bu metodun temel çalışma prensibi, güncel boolean değeri parametre olarak alması ve kullanıcının etkileşimi sonucunda değişen yeni boolean değerini geri döndürmesidir. Bu nedenle, döndürülen değeri bir değişkene atamak zorunludur.
Basit Bir Custom Inspector Örneği
Aşağıdaki örnek, bir MyComponent
adında basit bir MonoBehaviour sınıfı ve bu sınıf için özel bir Inspector’ın nasıl oluşturulduğunu göstermektedir. Bu Inspector’da, EditorGUILayout.Toggle()
kullanarak bir boolean değişkeni kontrol edeceğiz.
// MyComponent.cs
using UnityEngine;
public class MyComponent : MonoBehaviour
{
public bool ozellikEtkin;
public string mesaj = "Merhaba Unity!";
}
// MyComponentEditor.cs (Assets/Editor klasöründe olmalı)
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(MyComponent))]
public class MyComponentEditor : Editor
{
public override void OnInspectorGUI()
{
MyComponent myComponent = (MyComponent)target;
// Default Inspector'ı çizer (isteğe bağlı)
// base.OnInspectorGUI();
EditorGUILayout.LabelField("Özel Toggle Kontrolü");
// EditorGUILayout Toggle Kullanımı
myComponent.ozellikEtkin = EditorGUILayout.Toggle("Özellik Etkin Mi?", myComponent.ozellikEtkin);
if (myComponent.ozellikEtkin)
{
myComponent.mesaj = EditorGUILayout.TextField("Mesaj", myComponent.mesaj);
}
// Inspector'da yapılan değişiklikleri kaydetmek için
if (GUI.changed)
{
EditorUtility.SetDirty(target);
}
}
}
Bu örnekte, ozellikEtkin
değişkeni bir toggle ile kontrol edilmekte, bu özellik etkinse bir metin alanı görünür hale gelmektedir. GUI.changed
kontrolü ve EditorUtility.SetDirty(target)
çağrısı, Inspector’da yapılan değişikliklerin Unity tarafından algılanmasını ve kaydedilmesini sağlar. Bu, özellikle sahne kaydedilirken veya prefab güncellenirken önemlidir.
SerializedProperty ile Daha Güçlü EditorGUILayout Toggle Kullanımı
Doğrudan bir component’in public değişkenlerini değiştirmek yerine, Unity’nin SerializedObject
ve SerializedProperty
sistemini kullanmak çok daha iyi bir yaklaşımdır. Bu sistem, şunları sağlar:
- Undo/Redo Desteği: Yaptığınız değişikliklerin geri alınabilmesini sağlar.
- Çoklu Obje Düzenleme: Birden fazla GameObject’i aynı anda seçtiğinizde Inspector’ın doğru çalışmasını sağlar.
- Prefab Desteği: Prefab’larda yapılan değişikliklerin doğru şekilde uygulanmasını sağlar.
// MyComponentEditor.cs (SerializedProperty ile)
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(MyComponent))]
public class MyComponentEditor : Editor
{
private SerializedProperty ozellikEtkinProp;
private SerializedProperty mesajProp;
private void OnEnable()
{
// Değişkenleri SerializedProperty olarak bağlama
ozellikEtkinProp = serializedObject.FindProperty("ozellikEtkin");
mesajProp = serializedObject.FindProperty("mesaj");
}
public override void OnInspectorGUI()
{
// Değişiklikleri dinlemeye başla
serializedObject.Update();
EditorGUILayout.LabelField("Özel Toggle Kontrolü (SerializedProperty)");
// SerializedProperty ile EditorGUILayout Toggle Kullanımı
EditorGUILayout.PropertyField(ozellikEtkinProp, new GUIContent("Özellik Etkin Mi?"));
if (ozellikEtkinProp.boolValue)
{
EditorGUILayout.PropertyField(mesajProp, new GUIContent("Mesaj"));
}
// Değişiklikleri uygula
serializedObject.ApplyModifiedProperties();
}
}
Bu yaklaşımda EditorGUILayout.PropertyField()
metodunu kullandık. Bu metod, SerializedProperty
‘nin tipine göre uygun Editor kontrolünü otomatik olarak çizer. Yani bir boolean için toggle, string için metin alanı vs. çizer. Bu, EditorGUILayout Toggle Kullanımı
için en temiz ve güçlü yoldur.
Pratik İpuçları ve Gelişmiş Kullanım
1. Değişiklikleri Algılama ve Performans (`EditorGUI.BeginChangeCheck`)
Bazen sadece belirli bir değer değiştiğinde bir işlem yapmak isteyebilirsiniz. EditorGUI.BeginChangeCheck()
ve EditorGUI.EndChangeCheck()
metodları, bu kontrolü sağlar ve gereksiz hesaplamaları önleyerek performansı artırır.
// İçerideki kod bloğunda bir değişiklik olup olmadığını kontrol eder
if (EditorGUI.BeginChangeCheck())
{
bool yeniDurum = EditorGUILayout.Toggle("Durum", myComponent.durum);
if (EditorGUI.EndChangeCheck())
{
myComponent.durum = yeniDurum;
Debug.Log("Durum değişti: " + myComponent.durum);
}
}
SerializedProperty
kullanırken de benzer bir mantıkla çalışır, ancak serializedObject.ApplyModifiedProperties()
zaten bu kontrolü ve kaydetmeyi otomatik olarak halleder.
2. İçeriği Girintileme (`EditorGUI.indentLevel`)
Editor arayüzünüzde görsel hiyerarşi oluşturmak için girintileme kullanmak önemlidir. EditorGUI.indentLevel
statik değişkenini artırarak veya azaltarak bunu yapabilirsiniz.
EditorGUILayout.LabelField("Ayarlar:");
EditorGUI.indentLevel++;
myComponent.ozellikEtkin = EditorGUILayout.Toggle("Özellik Etkin Mi?", myComponent.ozellikEtkin);
if (myComponent.ozellikEtkin)
{
EditorGUI.indentLevel++;
myComponent.mesaj = EditorGUILayout.TextField("Mesaj", myComponent.mesaj);
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel--;
3. Koşullu Etkinleştirme/Devre Dışı Bırakma (`EditorGUI.BeginDisabledGroup`)
Bazı durumlarda, bir toggle’ın durumu başka bir ayara bağlı olabilir. Bu gibi durumlarda, bir kontrolü gri renkte gösterip etkileşimi engellemek için EditorGUI.BeginDisabledGroup()
kullanılabilir.
bool anaOzellikEtkin = EditorGUILayout.Toggle("Ana Özellik", myComponent.anaOzellikEtkin);
EditorGUI.BeginDisabledGroup(!anaOzellikEtkin);
{
// Ana özellik etkin değilse bu toggle pasif görünür
myComponent.altOzellikEtkin = EditorGUILayout.Toggle("Alt Özellik", myComponent.altOzellikEtkin);
}
EditorGUI.EndDisabledGroup();
4. Gelişmiş Etiketleme (`GUIContent`)
GUIContent
sınıfı, etiketlere ikonlar eklemek veya tooltip (ipucu metni) sağlamak için kullanılır. Bu, arayüzünüzü daha bilgilendirici hale getirir.
// Tooltip içeren bir toggle
myComponent.ozellikEtkin = EditorGUILayout.Toggle(new GUIContent("Özellik Etkin Mi?", "Bu özellik, bileşenin belirli davranışlarını kontrol eder."), myComponent.ozellikEtkin);
Yaygın Hatalar ve Çözümleri
1. Dönüş Değerini Atamamak
Hata: EditorGUILayout.Toggle("Aktif", myComponent.aktif);
Çözüm: EditorGUILayout.Toggle()
yeni değeri döndürdüğü için, bu değeri mutlaka değişkene atamalısınız: myComponent.aktif = EditorGUILayout.Toggle("Aktif", myComponent.aktif);
2. SerializedProperty Kullanmamak
Doğrudan public değişkenleri değiştirmek, özellikle Undo/Redo fonksiyonelliği ve çoklu obje düzenleme gibi temel Editor özelliklerinden mahrum kalmanıza neden olur. Bu, geliştirme sürecinde büyük sorunlara yol açabilir.
Çözüm: Her zaman SerializedObject
ve SerializedProperty
kullanarak değişkenlerinizi yönetin. Yukarıdaki örnekte gösterildiği gibi serializedObject.Update()
ve serializedObject.ApplyModifiedProperties()
çağrılarını unutmayın.
3. OnInspectorGUI Dışında Kullanmak
EditorGUILayout
metodları sadece Editor
sınıfının OnInspectorGUI()
metodunda veya EditorWindow
sınıfının OnGUI()
metodunda çağrılmalıdır. Başka yerlerde çağrılmaları hata verebilir veya beklenmedik davranışlara yol açabilir.
Çözüm: Editor GUI çizim kodlarınızın doğru metodlar içinde olduğundan emin olun.
Performans ve Optimizasyon Notları
Unity Editor GUI çizimi, oyun içi çizime göre daha az performans odaklıdır, ancak yine de dikkatli olmak önemlidir:
- Gereksiz Çizimden Kaçınma: Özellikle büyük veya karmaşık Inspector’larda, her frame’de tüm GUI elemanlarını yeniden çizmek yerine, sadece değişen kısımları güncellemek için
EditorGUI.BeginChangeCheck()
kullanın.SerializedProperty
kullanımı bu konuda zaten iyi bir soyutlama sağlar. - Otomatik Yerleşim (Auto-Layout):
EditorGUILayout
kullanmak, elemanların konum ve boyut hesaplamalarını Unity’ye bırakır. Bu, manuelGUI.Toggle()
veRect
hesaplamalarına göre genellikle daha verimlidir ve kod karmaşıklığını azaltır. OnEnable
‘da Property Bağlama:FindProperty
gibi pahalı işlemleriOnInspectorGUI
yerineOnEnable
metodunda yaparak Inspector’ın her çizildiğinde bu işlemlerin tekrarlanmasını önleyin.
Bu ipuçları, EditorGUILayout Toggle Kullanımı ile oluşturduğunuz arayüzlerin hem düzenli hem de performanslı olmasını sağlayacaktır.
Sonuç
EditorGUILayout.Toggle()
, Unity Editor’da etkileşimli ve kullanıcı dostu arayüzler oluşturmak için vazgeçilmez bir araçtır. Temel kullanımından SerializedProperty
ile entegrasyonuna, pratik ipuçlarından yaygın hatalara kadar bu makalede öğrendiklerinizle, Unity projelerinizde daha güçlü ve esnek özel Editor araçları geliştirebileceksiniz. Unutmayın, iyi tasarlanmış bir Editor arayüzü, geliştirme sürecinizi önemli ölçüde hızlandırabilir ve ekibinizin verimliliğini artırabilir.