Unity Eğitim
Dersler
Forum Sınav Merkezi Premium 💎
C# Dersleri

Unity Editor Scripting: Özel Inspector ve Araç Menüsü Oluşturma

Paylaşan: Unity Eğitim 05 November 2025 10 dakika okuma 68 görüntülenme

Unity oyun motoru, geliştiricilere güçlü bir görsel düzenleyici sunar. Ancak bazen varsayılan editör özellikleri, özel ihtiyaçlarımızı karşılamak için yeterli olmayabilir. İşte tam bu noktada Unity Editor Scripting devreye girer. Bu makalede, oyun geliştirme sürecinizi kişiselleştirmek ve hızlandırmak için Özel Inspector'lar (Custom Inspectors) nasıl oluşturulur ve Unity'nin üst menüsüne özel araçlar (Tools menüsü öğeleri) nasıl eklenir konularını derinlemesine inceleyeceğiz.

Unity Editor Scripting, geliştiricilere Unity Editor'ın davranışını genişletme ve özelleştirme yeteneği sunar. Bu sayede, karmaşık iş akışlarını otomatikleştirerek, özel bileşenler için daha sezgisel arayüzler tasarlayarak ve ekibinizin verimliliğini artırarak projelerinizde büyük bir fark yaratabilirsiniz. Özellikle büyük projelerde veya benzersiz oyun mekanikleri geliştirirken, editöre kendi özel araçlarınızı eklemek paha biçilmez bir avantaj sağlar.

Unity Editor Scripting Nedir ve Neden Önemlidir?

Unity Editor Scripting, Unity Editör'ün kendisini C# kodları ile programlayarak, varsayılan davranışlarını değiştirmeye veya yeni işlevler eklemeye olanak tanıyan bir dizi API'dir. Bu, oyunlarınızın çalışma zamanı (runtime) kodundan farklıdır; editör scriptleri sadece Unity Editör'de çalışır ve derlenmiş oyununuza dahil edilmez.

Neden Editor Scripting Kullanmalısınız?

  • İş Akışı Optimizasyonu: Tekrarlayan görevleri otomatikleştirin. Örneğin, sahnedeki tüm ışıkların yoğunluğunu tek bir tıklamayla ayarlayabilir veya belirli bir türdeki tüm objelerin materyallerini değiştirebilirsiniz.
  • Kullanıcı Dostu Arayüzler: Karmaşık bileşenler için varsayılan Inspector'ı daha anlaşılır ve interaktif bir arayüze dönüştürün. Bu, özellikle tasarımcılar ve diğer ekip üyeleri için büyük kolaylık sağlar.
  • Hata Azaltma: Özel doğrulama kuralları ekleyerek veya belirli girdileri kısıtlayarak hatalı konfigürasyonları önleyebilirsiniz.
  • Ekip Verimliliği: Ekibinize özel araçlar sağlayarak herkesin daha hızlı ve tutarlı çalışmasını sağlayın.

Editor Scriptleri Nereye Konulmalı?

Tüm editör scriptleri, projenizin Assets klasörü içinde Editor adında özel bir klasöre yerleştirilmelidir. Bu klasörün adı büyük harfle başlamalı ve tam olarak 'Editor' olmalıdır. Unity, bu klasördeki scriptleri otomatik olarak editör kodu olarak tanır ve oyunun derlenmiş çıktısına dahil etmez. Birden fazla Editor klasörünüz olabilir (örn: Assets/Scripts/Player/Editor, Assets/Materials/Editor).

Özel Inspector (Custom Inspector) Oluşturma

Varsayılan Inspector, bir MonoBehaviour veya ScriptableObject bileşenindeki tüm public değişkenleri gösterir. Ancak bazen bu yeterli olmaz. Örneğin, bir bileşenin karmaşık ayarları varsa veya Inspector'da bir düğme veya özel bir grafik göstermek istiyorsanız, bir Özel Inspector oluşturmanız gerekir.

Nasıl Oluşturulur?

Bir Özel Inspector oluşturmak için:

  1. Assets/Editor klasörü içinde yeni bir C# scripti oluşturun.
  2. Bu script, UnityEditor namespace'ini kullanmalı ve Editor sınıfından türemelidir.
  3. Inspector'ını özelleştirmek istediğiniz bileşeni belirtmek için scriptin üzerine [CustomEditor(typeof(YourComponent))] niteliğini ekleyin.
  4. OnInspectorGUI() metodunu override ederek kendi Inspector çiziminizi yapın.

İşte basit bir örnek:


using UnityEditor;
using UnityEngine;

// Inspector'ını özelleştireceğimiz MonoBehaviour
public class MyComponent : MonoBehaviour
{
    public int someValue = 10;
    public string someText = "Hello Unity";
    public bool showAdvancedSettings = false;

    public void DoSomething()
    {
        Debug.Log("Do Something called from " + gameObject.name);
    }
}

// MyComponent için Özel Inspector
[CustomEditor(typeof(MyComponent))]
public class MyComponentEditor : Editor
{
    public override void OnInspectorGUI()
    {
        // Hedef bileşenin bir referansını alın
        MyComponent myComponent = (MyComponent)target;

        // Inspector'da gösterilecek başlık
        EditorGUILayout.LabelField("Özel MyComponent Inspector", EditorStyles.boldLabel);

        // SerializedProperty kullanarak değerleri düzenleme (Undo desteği ve performans için önerilir)
        serializedObject.Update(); // Değişiklikleri okumak için

        SerializedProperty someValueProp = serializedObject.FindProperty("someValue");
        EditorGUILayout.PropertyField(someValueProp, new GUIContent("Bir Sayı Değeri"));

        SerializedProperty someTextProp = serializedObject.FindProperty("someText");
        EditorGUILayout.PropertyField(someTextProp, new GUIContent("Bir Metin"));

        // Özel bir buton ekleme
        if (GUILayout.Button("Bir Şey Yap"))
        {
            myComponent.DoSomething();
        }

        // Katlanabilir bir alan (Foldout) ekleyelim
        myComponent.showAdvancedSettings = EditorGUILayout.Foldout(myComponent.showAdvancedSettings, "Gelişmiş Ayarlar");
        if (myComponent.showAdvancedSettings)
        {
            EditorGUI.indentLevel++; // Girinti ekle
            EditorGUILayout.HelpBox("Bu gelişmiş bir ayar alanıdır. Buraya daha fazla UI elemanı ekleyebilirsiniz.", MessageType.Info);
            // Örneğin, bir kaydırıcı ekleyelim
            myComponent.someValue = EditorGUILayout.IntSlider("Ek Değer", myComponent.someValue, 0, 100);
            EditorGUI.indentLevel--; // Girintiyi kaldır
        }

        serializedObject.ApplyModifiedProperties(); // Değişiklikleri kaydetmek için
    }
}

Yukarıdaki örnekte, serializedObject.Update() ve serializedObject.ApplyModifiedProperties() çağrıları çok önemlidir. Bu metodlar, Inspector'da yapılan değişikliklerin Unity'nin Undo sistemi ile uyumlu olmasını ve performanslı bir şekilde kaydedilmesini sağlar. Ayrıca EditorGUILayout ve EditorGUI sınıfları, hazır Unity UI elemanlarını (butonlar, alanlar, kaydırıcılar vb.) Inspector'a eklemek için kullanılır.

Tools Menüsü Öğeleri Oluşturma

Unity'nin üst menüsüne (File, Edit, Assets, GameObject, Component, Window, Help) kendi özel menü öğelerinizi ekleyebilirsiniz. Genellikle bu tür araçlar Tools menüsü altına yerleştirilir. Bu, sahne üzerinde genel işlemler yapmak, veri oluşturmak veya toplu düzenlemeler yapmak için idealdir.

Nasıl Oluşturulur?

Bir Tools menüsü öğesi oluşturmak için:

  1. Assets/Editor klasörü içinde yeni bir C# scripti oluşturun.
  2. Bu script, UnityEditor namespace'ini kullanmalı ve statik bir metod içermelidir.
  3. Metodun üzerine [MenuItem("Tools/MyCustomTool")] niteliğini ekleyin. Buradaki yol, menüdeki hiyerarşiyi belirler.

İşte basit bir örnek:


using UnityEditor;
using UnityEngine;

public class CustomToolMenu
{
    // Yeni bir boş GameObject oluşturan menü öğesi
    [MenuItem("Tools/Yeni Boş GameObject Oluştur")]
    public static void CreateEmptyGameObject()
    {
        GameObject newGameObject = new GameObject("Yeni Boş Nesne");
        Selection.activeGameObject = newGameObject; // Oluşturulan nesneyi seçili hale getir
        Debug.Log("Yeni boş GameObject oluşturuldu: " + newGameObject.name);
        Undo.RegisterCreatedObjectUndo(newGameObject, "Yeni Boş Nesne Oluştur"); // Undo desteği
    }

    // Seçili objelerin konumunu sıfırlayan menü öğesi
    [MenuItem("Tools/Seçili Objelerin Konumunu Sıfırla")]
    public static void ResetSelectedPositions()
    {
        if (Selection.gameObjects.Length == 0)
        {
            EditorUtility.DisplayDialog("Uyarı", "Lütfen en az bir GameObject seçin.", "Tamam");
            return;
        }

        foreach (GameObject go in Selection.gameObjects)
        {
            Undo.RecordObject(go.transform, "Objelerin Konumunu Sıfırla"); // Undo desteği
            go.transform.position = Vector3.zero;
            go.transform.rotation = Quaternion.identity;
            go.transform.localScale = Vector3.one;
        }
        Debug.Log(Selection.gameObjects.Length + " objenin konumu sıfırlandı.");
    }

    // Menü öğesinin ne zaman aktif olacağını belirleyen doğrulama metodu
    // Aynı menü yolu ve 'true' parametresi ile kullanılır.
    [MenuItem("Tools/Seçili Objelerin Konumunu Sıfırla", true)]
    public static bool ValidateResetSelectedPositions()
    {
        // Sadece en az bir GameObject seçiliyse menü öğesi aktif olsun
        return Selection.gameObjects.Length > 0;
    }
}

[MenuItem] niteliği, menü yolunun yanı sıra bir öncelik değeri ve bir doğrulama metodu da alabilir. Doğrulama metodu (ikinci örnekteki ValidateResetSelectedPositions gibi), menü öğesinin ne zaman etkin veya devre dışı olacağını belirlemenizi sağlar. Bu, kullanıcı deneyimini önemli ölçüde iyileştirir.

Pratik İpuçları

1. SerializedProperty ve SerializedObject Kullanımı

Özel Inspector geliştirirken, doğrudan target objesindeki public alanlara erişmek yerine SerializedObject ve SerializedProperty kullanmak en iyi uygulamadır. Bu yaklaşım, Unity'nin Undo/Redo sistemini otomatik olarak destekler, prefab override'ları ile düzgün çalışır ve performans açısından daha verimlidir. Yukarıdaki Özel Inspector örneğinde bu kullanım gösterilmiştir.

2. Değişiklikleri Kaydetme ve Undo Desteği

Editor scriptlerinizle bir varlık (asset) veya sahnedeki bir GameObject üzerinde değişiklik yaptığınızda, bu değişikliklerin kalıcı olması ve Undo/Redo sistemi tarafından desteklenmesi önemlidir.

  • GameObject veya Component için: Undo.RecordObject(object, "Değişiklik Açıklaması") veya Undo.RegisterCreatedObjectUndo(object, "Oluşturulan Nesne Açıklaması") kullanın.
  • Asset için: EditorUtility.SetDirty(assetObject) çağırarak Unity'ye assetin değiştiğini bildirin, ardından AssetDatabase.SaveAssets() ile değişiklikleri kaydedin.

3. Scene View'da Görsel Geri Bildirim (Handles ve Gizmos)

Özel Inspector'larınız veya araçlarınız için Scene View'da görsel geri bildirim sağlamak, geliştirme sürecini çok daha sezgisel hale getirebilir. OnSceneGUI() metodunu override ederek Handles sınıfını, OnDrawGizmos() veya OnDrawGizmosSelected() metodlarını kullanarak Gizmos sınıfını kullanabilirsiniz. Örneğin, özel bir bölgeyi veya bir rotayı görselleştirmek için idealdir.


using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(MyComponent))]
public class MyComponentEditor : Editor
{
    // ... OnInspectorGUI kodunuz ...

    void OnSceneGUI()
    {
        MyComponent myComponent = (MyComponent)target;
        // Scene View'da bir küre çizin
        Handles.color = Color.red;
        Handles.SphereHandleCap(0, myComponent.transform.position + Vector3.up * 2, Quaternion.identity, 1f, EventType.Repaint);
        Handles.Label(myComponent.transform.position + Vector3.up * 3, "My Component Here");
    }
}

Yaygın Hatalar ve Çözümleri

1. Editor Scriptlerini Yanlış Klasöre Koymak

Hata: Editor scriptlerini Assets/Editor klasörü dışına koymak. Bu durumda scriptler derleme hatası verir çünkü UnityEditor namespace'i sadece editör ortamında kullanılabilir.

Çözüm: Tüm editör scriptlerinizin (Editor sınıfından türeyenler veya [MenuItem] niteliği kullananlar) kesinlikle Assets/Editor veya alt klasörlerinden birinde olduğundan emin olun.

2. serializedObject.Update() ve ApplyModifiedProperties() Unutmak

Hata: Özel Inspector içinde serializedObject.Update() ve serializedObject.ApplyModifiedProperties() çağırmayı unutmak. Bu, Inspector'da yapılan değişikliklerin bileşene yansımamasına veya Undo sisteminin çalışmamasına neden olur.

Çözüm: OnInspectorGUI() metodunun başında serializedObject.Update() ve sonunda serializedObject.ApplyModifiedProperties() çağrılarını eklediğinizden emin olun.

3. Doğrudan Target Değişkenlerini Değiştirmek

Hata: target objesinin public değişkenlerini doğrudan değiştirmek (örn: myComponent.someValue = newValue;) yerine SerializedProperty kullanmamak.

Çözüm: Küçük ve basit değişiklikler için kabul edilebilir olsa da, Undo desteği ve prefab uyumluluğu için her zaman SerializedProperty kullanmaya çalışın. Eğer doğrudan değişiklik yapıyorsanız, Undo.RecordObject() kullanarak manuel olarak Undo desteği sağlamalısınız.

Performans ve Optimizasyon Notları

OnInspectorGUI() metodu, Inspector penceresi odaklandığında, bir değer değiştiğinde veya hatta sadece fare hareket ettiğinde bile sık sık çağrılabilir. Bu nedenle, bu metod içinde ağır hesaplamalar yapmaktan kaçınmak önemlidir.

  • Ağır İşlemlerden Kaçının: Özellikle döngüler, dosya okuma/yazma veya karmaşık matematiksel işlemler gibi kaynak tüketen kodları OnInspectorGUI() dışına taşıyın veya sadece gerektiğinde çalışacak şekilde optimize edin.
  • Önbellekleme (Caching): Sık kullanılan referansları (örneğin, serializedObject.FindProperty() çağrılarının sonuçlarını) bir kez başlatma (OnEnable() içinde) ve önbelleğe alma yoluyla tekrar tekrar arama maliyetinden kaçının.
  • Değişiklik Kontrolü: EditorGUI.BeginChangeCheck() ve EditorGUI.EndChangeCheck() metodlarını kullanarak sadece kullanıcı arayüzünde bir değişiklik yapıldığında belirli kod bloklarını çalıştırın. Bu, gereksiz güncellemeleri önler.

public override void OnInspectorGUI()
{
    serializedObject.Update();

    EditorGUI.BeginChangeCheck(); // Değişiklik kontrolünü başlat

    // UI elemanlarınızı buraya çizin
    EditorGUILayout.PropertyField(serializedObject.FindProperty("someValue"));

    if (EditorGUI.EndChangeCheck()) // Eğer herhangi bir UI elemanında değişiklik olduysa
    {
        // Sadece değişiklik olduğunda çalışacak kod
        Debug.Log("Inspector'da bir değer değişti!");
    }

    serializedObject.ApplyModifiedProperties();
}

Sonuç

Unity Editor Scripting, Özel Inspector'lar ve Tools menüsü öğeleri aracılığıyla Unity Editor'ı kendi ihtiyaçlarınıza göre şekillendirmenizi sağlayan inanılmaz güçlü araçlardır. Bu yetenekleri kullanarak, geliştirme sürecinizi hızlandırabilir, ekip verimliliğinizi artırabilir ve oyununuz için daha sağlam, kullanıcı dostu araçlar oluşturabilirsiniz. Başlangıçta biraz karmaşık görünse de, temel prensipleri kavradıktan sonra, Unity Editor Scripting'in oyun geliştirme iş akışınızda ne kadar büyük bir fark yaratabileceğini göreceksiniz. Denemekten ve yaratıcı olmaktan çekinmeyin!

🧠 Ders Sonu Değerlendirme Testi

Dersi tamamladıktan sonra bilgilerinizi test edin ve ekstra puanlar kazanın.

🔥 +50 XP Ödül
🔒

Sınava Katılmak İçin Giriş Yapın

Bu ders sonu testini çözebilmek, bilginizi test edip **+50 XP** kazanmak ve **Sınav Şampiyonu** rozetinin kilidini açmak için üye girişi yapmalısınız.

Yorumlar (0)

Yorum yazabilmek ve derslere katkıda bulunabilmek için giriş yapmalısınız.

İlk yorumu siz yapın!