Unity oyun motoru, geliştiricilere sadece oyun yapma imkanı sunmakla kalmaz, aynı zamanda geliştirme sürecini kolaylaştırmak için editör ortamını kişiselleştirme ve genişletme fırsatları da sağlar. Bu makalede, Unity EditorWindow sınıfını kullanarak kendi özel editör pencerelerinizi nasıl oluşturacağınızı, iş akışınızı nasıl hızlandıracağınızı ve editörünüzü nasıl daha verimli hale getireceğinizi detaylı bir şekilde inceleyeceğiz.
Özel Editör Penceresi Nedir ve Neden Kullanılır?
Unity editöründe gördüğünüz Inspector, Project, Hierarchy gibi pencerelerin hepsi aslında Unity’nin kendi içerisinde oluşturduğu özel pencerelerdir. EditorWindow sınıfı, geliştiricilere bu tür pencereleri kendi projeleri için oluşturma gücü verir. Peki neden bir özel editör penceresine ihtiyacınız olsun ki?
- İş Akışını Hızlandırma: Sık tekrar eden görevleri otomatikleştiren veya karmaşık ayarları tek bir yerden yönetmenizi sağlayan araçlar oluşturabilirsiniz.
- Veri Yönetimi: Proje genelindeki belirli verileri (örneğin, oyun ayarları, seviye verileri) merkezi bir arayüzden düzenleyebilirsiniz.
- Kullanıcı Deneyimi: Takımınızın veya kendi kullanımınız için daha sezgisel ve özelleştirilmiş bir arayüz sunabilirsiniz.
- Görselleştirme: Oyununuzun belirli yönlerini (örneğin, yol bulma ağları, seviye haritaları) editör içinde görselleştirebilirsiniz.
Unity EditorWindow Temelleri
Bir Unity EditorWindow oluşturmak oldukça basittir. Temel olarak, EditorWindow sınıfından türeyen bir C# betiği oluşturmanız ve bazı temel metotları uygulamanız gerekir.
1. Editor Klasörü Oluşturma
Editör betikleri, oyunun derlenmiş haline dahil edilmemelidir. Bu nedenle, projenizin Assets klasörü içinde mutlaka ‘Editor’ adında bir klasör oluşturmalısınız. Tüm özel editör betiklerinizi bu klasöre yerleştirin.
2. Temel EditorWindow Yapısı
Yeni bir C# betiği oluşturun (örneğin, MyCustomWindow.cs) ve içeriğini aşağıdaki gibi düzenleyin:
using UnityEditor;
using UnityEngine;
public class MyCustomWindow : EditorWindow
{
// Pencereyi Unity menüsüne eklemek için MenuItem kullanıyoruz.
[MenuItem("Tools/My Custom Window")]
public static void ShowWindow()
{
// Mevcut pencereyi getir veya yeni bir tane oluştur.
MyCustomWindow window = GetWindow<MyCustomWindow>("Özel Pencere");
window.minSize = new Vector2(300, 200);
window.maxSize = new Vector2(800, 600);
}
// Pencerenin içeriğini çizen metot.
void OnGUI()
{
GUILayout.Label("Merhaba, Özel Pencere!", EditorStyles.boldLabel);
if (GUILayout.Button("Bir Şey Yap!"))
{
Debug.Log("Butona tıklandı!");
}
}
}
Yukarıdaki kodda önemli noktalar:
using UnityEditor;: Editor sınıflarını kullanabilmek için bu namespace gereklidir.[MenuItem("Tools/My Custom Window")]: Bu nitelik (attribute), Unity’nin üst menüsüne ‘Tools’ altında ‘My Custom Window’ adında bir giriş ekler. TıklandığındaShowWindow()metodu çağrılır.GetWindow<MyCustomWindow>("Özel Pencere"): Bu statik metot, belirtilen türde birEditorWindowörneğini döndürür. Eğer böyle bir pencere zaten açıksa onu döndürür, yoksa yeni bir tane oluşturur. Parametre, pencerenin başlığını belirler.minSizevemaxSize: Pencerenin minimum ve maksimum boyutlarını ayarlamanızı sağlar.OnGUI(): Bu metot, pencere içeriğinin çizildiği yerdir. Her karede birden çok kez çağrılabilir. Tüm UI elemanları bu metot içinde çizilir.GUILayoutveEditorGUILayout: Bu sınıflar, Unity editöründe UI elemanları (düğmeler, metin alanları, kaydırıcılar vb.) oluşturmak için kullanılır.EditorGUILayout, editör özgü kontroller (örneğin,ObjectField) sağlar ve standartGUILayout‘a benzer şekilde otomatik düzenleme yapar.
Orta Seviye Detaylar ve Kullanım
Pencere Başlığı ve İkonu
Pencerenizin başlığını ve isteğe bağlı olarak bir ikonunu ayarlamak için titleContent özelliğini kullanabilirsiniz:
public static void ShowWindow()
{
MyCustomWindow window = GetWindow<MyCustomWindow>();
window.titleContent = new GUIContent("Özel Pencere", EditorGUIUtility.IconContent("d_UnityEditor.EditorWindow").image);
// ... diğer ayarlar
}
EditorGUIUtility.IconContent("d_UnityEditor.EditorWindow").image ile Unity’nin dahili ikonlarından birini kullanabilirsiniz. Başka bir ikon kullanmak isterseniz, projenizdeki bir Texture2D nesnesini de atayabilirsiniz.
Veri Kaydetme ve Yükleme
EditorWindow‘lar varsayılan olarak durumlarını kaydetmez. Pencere kapatıldığında veya Unity yeniden başlatıldığında veriler kaybolur. Verileri kalıcı hale getirmek için EditorPrefs veya ScriptableObject kullanabilirsiniz.
EditorPrefs Kullanımı
Küçük miktardaki veriler için EditorPrefs idealdir:
private string myText = "";
void OnGUI()
{
myText = EditorGUILayout.TextField("Metin Alanı:", myText);
if (GUILayout.Button("Kaydet"))
{
EditorPrefs.SetString("MyCustomWindow_Text", myText);
Debug.Log("Veri kaydedildi: " + myText);
}
if (GUILayout.Button("Yükle"))
{
myText = EditorPrefs.GetString("MyCustomWindow_Text", "Varsayılan Değer");
Debug.Log("Veri yüklendi: " + myText);
}
}
// Pencere kapatılırken veriyi kaydetmek için
void OnDestroy()
{
EditorPrefs.SetString("MyCustomWindow_Text", myText);
}
Pratik İpuçları
1. ScriptableObject ile Gelişmiş Veri Yönetimi
Daha karmaşık ve yapılandırılmış veriler için ScriptableObject kullanmak çok daha iyidir. Bu sayede verilerinizi bir asset olarak kaydedebilir ve projenizle birlikte versiyonlayabilirsiniz.
// MyEditorData.cs (Assets/Editor dışında olabilir)
using UnityEngine;
[CreateAssetMenu(fileName = "NewEditorData", menuName = "Editor/My Editor Data")]
public class MyEditorData : ScriptableObject
{
public string message = "Varsayılan Mesaj";
public int count = 0;
}
// MyCustomWindow.cs (Assets/Editor içinde)
using UnityEditor;
using UnityEngine;
public class MyCustomWindow : EditorWindow
{
private MyEditorData editorData;
[MenuItem("Tools/My Data Window")]
public static void ShowWindow()
{
GetWindow<MyCustomWindow>("Veri Penceresi");
}
void OnEnable()
{
// Projeden mevcut ScriptableObject'i bul veya oluştur
editorData = AssetDatabase.LoadAssetAtPath<MyEditorData>("Assets/MyEditorData.asset");
if (editorData == null)
{
editorData = ScriptableObject.CreateInstance<MyEditorData>();
AssetDatabase.CreateAsset(editorData, "Assets/MyEditorData.asset");
AssetDatabase.SaveAssets();
}
}
void OnGUI()
{
if (editorData == null) return;
EditorGUILayout.LabelField("Veri Yöneticisi", EditorStyles.boldLabel);
editorData.message = EditorGUILayout.TextField("Mesaj:", editorData.message);
editorData.count = EditorGUILayout.IntField("Sayım:", editorData.count);
if (GUI.changed)
{
EditorUtility.SetDirty(editorData);
AssetDatabase.SaveAssets();
}
}
}
Bu yaklaşım, pencere kapansa bile verilerinizin bir asset olarak kalıcı olmasını sağlar.
2. Kaydırılabilir Alanlar (ScrollView) Kullanımı
Pencerenizin içeriği çok fazla olduğunda kaydırılabilir bir alan oluşturmak kullanıcı deneyimini artırır:
private Vector2 scrollPos;
void OnGUI()
{
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
// Buraya tüm UI elemanlarınızı yerleştirin.
for (int i = 0; i < 50; i++)
{
EditorGUILayout.LabelField($"Öğe {i}");
}
EditorGUILayout.EndScrollView();
}
3. Seçili Nesnelerle Etkileşim
Editörde seçili olan nesnelerle etkileşime geçmek için Selection sınıfını kullanabilirsiniz:
void OnGUI()
{
GameObject selectedObject = Selection.activeGameObject;
if (selectedObject != null)
{
EditorGUILayout.LabelField("Seçili Nesne:", selectedObject.name);
if (GUILayout.Button("Seçili Nesneyi Klonla"))
{
GameObject.Instantiate(selectedObject);
}
}
else
{
EditorGUILayout.LabelField("Hiçbir nesne seçili değil.");
}
}
Yaygın Hatalar ve Çözümleri
-
OnGUI()içinde Ağır İşlemler Yapmak:OnGUI()metodu her karede birden çok kez çağrılabilir. Bu nedenle, burada dosya okuma/yazma, karmaşık hesaplamalar gibi performans düşürücü işlemlerden kaçınmalısınız. Bu tür işlemleri bir buton tıklaması gibi olaylara bağlayın veya ayrı bir metotta çalıştırın ve sonucu önbelleğe alın. -
Editor Klasörünü Unutmak: Editör betiklerini
Assets/Editorklasörüne koymayı unutmak, oyununuzu derlemeye çalıştığınızda hatalara yol açar, çünküUnityEditornamespace’i oyun derlemesine dahil edilmez. -
Veri Kaybı: Pencere kapatıldığında veya Unity yeniden başlatıldığında
EditorWindow‘daki değişkenlerin sıfırlanması. Çözüm olarakEditorPrefsveyaScriptableObjectkullanarak verilerinizi kalıcı hale getirin. -
GUI.changedKullanımını Atlamak: Özellikle Inspector benzeri pencerelerde, kullanıcı bir değeri değiştirdiğinde bunu fark edipEditorUtility.SetDirty()veAssetDatabase.SaveAssets()ile asset’i kaydetmek önemlidir. Aksi takdirde, değişiklikleriniz Unity tarafından kaydedilmez.
Performans ve Optimizasyon Notları
- Gereksiz Repaint’lerden Kaçının:
EditorWindow‘unOnGUI()metodu sürekli çağrılır. Eğer pencerenizin içeriği statikse ve sadece belirli bir olayda (örneğin, bir butona tıklandığında veya bir değer değiştiğinde) güncellenmesi gerekiyorsa,Repaint()metodunu sadece gerektiğinde çağırarak performansı artırabilirsiniz. - Karmaşık Çizimden Kaçının: Özellikle özel grafikler veya çok sayıda UI elemanı çiziyorsanız, bunları optimize etmeye çalışın.
- Önbelleğe Alma: Sık kullanılan referansları (örneğin, bir
ScriptableObjectörneği)OnEnable()metodunda önbelleğe alın,OnGUI()içinde tekrar tekrar yüklemekten kaçının.
Unity EditorWindow, Unity geliştiricileri için güçlü bir araçtır. Bu makaledeki bilgilerle, kendi özel editör pencerelerinizi oluşturmaya başlayabilir, geliştirme sürecinizi kişiselleştirebilir ve projelerinizde daha verimli çalışabilirsiniz. Unutmayın, iyi tasarlanmış bir Unity EditorWindow, geliştirme sürenizi önemli ölçüde kısaltabilir ve takımınızın iş akışını iyileştirebilir.



