Unity Handles.DrawLine: Sahne İçi Görsel Yardımcılar Oluşturma

Unity Editör'ünde Handles.DrawLine() ile özel çizgiler çizerek sahne içi araçlarınızı ve hata ayıklama görsellerinizi geliştirin. Detaylı rehber ve pratik ipuçları.

Giriş: Unity Editöründe Görsel Güç

Unity geliştirme sürecinde, oyun nesnelerinin veya mantık akışının sahne içinde görselleştirilmesi, hem hata ayıklama hem de özel araçlar geliştirme açısından kritik öneme sahiptir. İşte tam bu noktada Unity’nin Handles sınıfı devreye girer. Özellikle Unity Handles.DrawLine metodu, sahne içinde kolayca çizgi çekmemizi sağlayarak, nesneler arası ilişkileri, hareket yönlerini, etki alanlarını veya özel yol sistemlerini görselleştirmek için mükemmel bir araç sunar. Bu makalede, Handles.DrawLine() metodunun temelden ileri seviyeye kullanımını, pratik ipuçlarını, yaygın hataları ve performans notlarını detaylı bir şekilde inceleyeceğiz.

Handles.DrawLine() Temelleri: Çizgi Çizmenin İlk Adımları

Handles sınıfı, Unity Editör’ünde görsel elemanlar (çizgiler, küreler, oklar vb.) çizmek için kullanılan bir araç setidir. Bu görsel elemanlar yalnızca Editör’de görünür ve oyunun çalışma zamanı (runtime) performansını etkilemez. Genellikle özel Editör script’leri içinde veya bir MonoBehaviour sınıfının OnDrawGizmos() ya da OnSceneGUI() metotlarında kullanılırlar.

Handles vs. Gizmos

Gizmos sınıfı da benzer şekilde görsel yardımcılar sunar, ancak Handles, Gizmos‘a göre daha fazla kontrol ve etkileşim imkanı sunar. Örneğin, Handles ile çizdiğiniz elemanları fare ile seçebilir, sürükleyebilir veya değiştirebilirsiniz. Unity Handles.DrawLine, bu esnekliği Editör içinde çizgi çizmek için sağlar.

OnSceneGUI() Metodu ve Kullanımı

Handles sınıfını genellikle bir MonoBehaviour için özel bir Editor script’i oluşturduğunuzda kullanırsınız. Bu özel Editör script’inde OnSceneGUI() metodunu override ederek sahne görünümüne kendi çizimlerinizi ekleyebilirsiniz. İşte temel bir Unity Handles.DrawLine kullanımı:


using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(MyLineDrawer))]
public class MyLineDrawerEditor : Editor
{
    public override void OnSceneGUI()
    {
        MyLineDrawer myLineDrawer = (MyLineDrawer)target;

        // Çizginin rengini belirle
        Handles.color = Color.red;

        // İki nokta arasına bir çizgi çiz
        Handles.DrawLine(myLineDrawer.startPoint, myLineDrawer.endPoint, 5f);

        // İsteğe bağlı olarak noktalara tutamaç ekleyebiliriz
        myLineDrawer.startPoint = Handles.FreeMoveHandle(myLineDrawer.startPoint, Quaternion.identity, 0.5f, Vector3.one, Handles.SphereHandleCap);
        myLineDrawer.endPoint = Handles.FreeMoveHandle(myLineDrawer.endPoint, Quaternion.identity, 0.5f, Vector3.one, Handles.SphereHandleCap);

        // Yapılan değişiklikleri kaydetmek için
        if (GUI.changed)
        {
            EditorUtility.SetDirty(myLineDrawer);
        }
    }
}

// Bu script'i bir GameObject'e ekleyin
public class MyLineDrawer : MonoBehaviour
{
    public Vector3 startPoint = Vector3.zero;
    public Vector3 endPoint = Vector3.forward * 5;
}

Yukarıdaki örnekte, MyLineDrawer adında bir MonoBehaviour için özel bir Editör oluşturduk. OnSceneGUI() içinde Handles.color ile çizginin rengini kırmızıya ayarladık ve Handles.DrawLine(myLineDrawer.startPoint, myLineDrawer.endPoint, 5f) ile başlangıç ve bitiş noktaları arasına 5 birim kalınlığında bir çizgi çektik. Ayrıca, Handles.FreeMoveHandle kullanarak bu noktaları sahne içinde sürükleyebilir hale getirdik.

Orta Seviye Detaylar: Çizgilerle Daha Fazlası

Unity Handles.DrawLine sadece iki nokta arasına düz bir çizgi çekmekten ibaret değildir. Çeşitli parametreler ve Handles sınıfının diğer özellikleri ile daha karmaşık görselleştirmeler yapabilirsiniz.

  • Kalınlık ve Cap Fonksiyonları: Handles.DrawLine(Vector3 start, Vector3 end, float thickness) metodu kalınlık belirtmenizi sağlar. Ayrıca Handles.DrawLine(Vector3 start, Vector3 end, Handles.CapFunction capFunction, float thickness) ile çizginin uç noktalarına özel bir “kapak” (cap) fonksiyonu uygulayabilirsiniz, örneğin ok ucu gibi.
  • Renk ve Işıklandırma: Handles.color ile çizim rengini ayarlayabilir, Handles.lighting ile çizimlerin ışıklandırılıp ışıklandırılmayacağını kontrol edebilirsiniz.
  • Z-Test: Handles.zTest özelliği, çizilen objelerin derinlik testi yapıp yapmayacağını belirler. Bu sayede, objelerin arkasında kalan çizgilerin görünüp görünmeyeceğini kontrol edebilirsiniz. Örneğin, Handles.zTest = CompareFunction.LessEqual; derinlik testi yapar, CompareFunction.Always; ise her zaman görünür olmasını sağlar.
  • Dönüşümler (Transformations): Handles.matrix ile çizimlerinizi belirli bir transform matrisi altında yapabilirsiniz. Bu, bir objenin yerel koordinat sisteminde çizim yapmak istediğinizde çok kullanışlıdır.
  • Etkileşimli Araçlar: EditorGUI.BeginChangeCheck() ve EditorGUI.EndChangeCheck() blokları arasında yapılan değişiklikleri algılayarak, sahne içi manipülasyonlar sonrası Editör’ü güncellemek ve değişiklikleri kaydetmek için kullanılır.

Pratik İpuçları ve Kullanım Senaryoları

İpucu 1: Özel Yol Sistemleri ve Bağlantı Noktaları

Bir oyun içinde düşmanların takip edeceği yollar, oyuncunun geçiş noktaları veya bir dizi objenin birbiriyle bağlantısını görselleştirmek için Unity Handles.DrawLine harika bir çözümdür. Örneğin, bir array içindeki Transform noktalarını birbirine bağlayan çizgiler çizebilirsiniz:


public class PathManager : MonoBehaviour
{
    public Transform[] pathPoints;

#if UNITY_EDITOR
    void OnDrawGizmos()
    {
        if (pathPoints == null || pathPoints.Length < 2) return;

        Handles.color = Color.cyan;
        for (int i = 0; i < pathPoints.Length - 1; i++)
        {
            if (pathPoints[i] != null && pathPoints[i+1] != null)
            {
                Handles.DrawLine(pathPoints[i].position, pathPoints[i+1].position, 3f);
            }
        }
    }
#endif
}

Bu kod bloğu, pathPoints dizisindeki her bir noktayı bir sonraki noktaya bağlayan camgöbeği renginde çizgiler çizer. OnDrawGizmos() yerine OnSceneGUI() içinde kullanıldığında, bu noktalara Handles.PositionHandle ekleyerek onları sahne içinde sürükleyip yol sisteminizi interaktif olarak tasarlayabilirsiniz.

İpucu 2: Gelişmiş Hata Ayıklama Görselleştirmesi

Raycast’ler, alan kontrolleri (küre, kutu) veya çarpışma alanları gibi karmaşık hata ayıklama senaryolarını görselleştirmek, sorunları anlamak için hayati öneme sahiptir. Unity Handles.DrawLine ile bu testleri çok daha anlaşılır hale getirebilirsiniz.


using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(RaycastDebugger))]
public class RaycastDebuggerEditor : Editor
{
    public override void OnSceneGUI()
    {
        RaycastDebugger debugger = (RaycastDebugger)target;

        // Ray'i çiz
        Handles.color = Color.blue;
        Vector3 rayOrigin = debugger.transform.position + debugger.transform.up * 0.5f;
        Vector3 rayDirection = debugger.transform.forward * debugger.rayDistance;
        Handles.DrawLine(rayOrigin, rayOrigin + rayDirection, 2f);

        RaycastHit hit;
        if (Physics.Raycast(rayOrigin, debugger.transform.forward, out hit, debugger.rayDistance))
        {
            // Çarpışma noktasını ve normalini çiz
            Handles.color = Color.green;
            Handles.DrawLine(rayOrigin, hit.point, 2f);
            Handles.color = Color.yellow;
            Handles.DrawLine(hit.point, hit.point + hit.normal * 1f, 3f);
            Handles.SphereHandleCap(0, hit.point, Quaternion.identity, 0.2f, EventType.Repaint);
        }
        else
        {
            // Çarpışma yoksa ray'i kırmızı çiz
            Handles.color = Color.red;
            Handles.DrawLine(rayOrigin, rayOrigin + rayDirection, 2f);
        }

        Handles.color = Color.white; // Rengi sıfırla
    }
}

public class RaycastDebugger : MonoBehaviour
{
    public float rayDistance = 10f;
}

Bu örnekte, bir raycast’in başlangıç noktasından nereye gittiğini ve bir şeye çarpıp çarpmadığını görselleştirmek için Unity Handles.DrawLine kullanılıyor. Çarpışma varsa yeşil bir çizgi ve sarı normal vektörü, çarpışma yoksa kırmızı bir çizgi çizilir.

İpucu 3: Editör Araçlarında Etkileşimli Alanlar

Özel Editör araçları geliştirirken, objelerin etki alanlarını veya belirli sınırları sahne içinde görselleştirmek isteyebilirsiniz. Örneğin, bir kameranın görüş konisini veya bir AI düşmanının görüş açısını Unity Handles.DrawLine ile çizebilir ve hatta bu alanları diğer Handles fonksiyonlarıyla etkileşimli hale getirebilirsiniz.


// Basit bir görüş konisi çizimi
void DrawFOV(Vector3 origin, Vector3 forward, float fovAngle, float range)
{
    Handles.color = Color.blue;
    Quaternion leftRayRotation = Quaternion.AngleAxis(-fovAngle / 2, Vector3.up);
    Quaternion rightRayRotation = Quaternion.AngleAxis(fovAngle / 2, Vector3.up);

    Vector3 leftRayDirection = leftRayRotation * forward * range;
    Vector3 rightRayDirection = rightRayRotation * forward * range;

    Handles.DrawLine(origin, origin + leftRayDirection);
    Handles.DrawLine(origin, origin + rightRayDirection);
    Handles.DrawWireArc(origin, Vector3.up, leftRayDirection, fovAngle, range);
}

Bu fonksiyon, belirli bir noktadan çıkan bir görüş konisi çizer. Handles.DrawWireArc ile koninin yayını da çizebilirsiniz. Unity Handles.DrawLine ve diğer Handles fonksiyonlarını birleştirerek çok güçlü ve görsel Editör araçları oluşturabilirsiniz.

Yaygın Hatalar ve Çözümleri

Hata 1: Handles.DrawLine()’ı Yanlış Yerde Çağırmak

Sorun: Handles.DrawLine() veya diğer Handles fonksiyonlarını Update(), Start() gibi çalışma zamanı metotlarında çağırmak. Bu durum derleme hatalarına veya Editör’de çizimlerin görünmemesine neden olur.

Çözüm: Handles sınıfı, yalnızca Unity Editör’ünde çalışmak üzere tasarlanmıştır. Bu nedenle, çizim kodlarınızı her zaman bir Editor script’inin OnSceneGUI() metodu içinde veya MonoBehaviour‘ın OnDrawGizmos() / OnDrawGizmosSelected() metotları içinde çağırmalısınız. #if UNITY_EDITOR ön işlemci direktifini kullanarak çalışma zamanında bu kodların derlenmesini engelleyebilirsiniz.

Hata 2: Handles.color’ı Sıfırlamayı Unutmak

Sorun: Birden fazla Handles çizimi yaptığınızda, bir çizim için ayarladığınız Handles.color diğer tüm çizimleri etkileyebilir ve beklenmedik renklerde görünmelerine neden olabilir.

Çözüm: Her çizim bloğundan sonra veya Editör kodunuzun sonunda Handles.color = Color.white; (veya Handles.color = originalColor;) şeklinde rengi varsayılan değere sıfırlamak iyi bir pratiktir. Alternatif olarak, mevcut rengi bir değişkende saklayıp sonra geri yükleyebilirsiniz.

Hata 3: Çizgilerin Görünmemesi veya Yanlış Çizilmesi

Sorun: Unity Handles.DrawLine ile çizdiğiniz çizgiler sahne görünümünde hiç görünmeyebilir veya beklediğinizden farklı görünebilir.

Çözüm:

  • Objenin Seçili Olduğundan Emin Olun: Eğer özel bir Editor script’i kullanıyorsanız, Editör’de ilgili GameObject‘in seçili olması gerekir.
  • Gizmos Menüsü: Sahne görünümünün sağ üst köşesindeki “Gizmos” menüsünden ilgili Gizmo türlerinin açık olduğundan emin olun.
  • Kamera Açısı ve Z-Test: Çizgiler kamera görüş alanının dışında olabilir veya Handles.zTest ayarları nedeniyle diğer objelerin arkasında kalıp görünmeyebilir. Handles.zTest = CompareFunction.Always; kullanarak derinlik testini devre dışı bırakmayı deneyebilirsiniz.
  • Konum ve Ölçek: Çizgi başlangıç ve bitiş noktalarının doğru koordinatlarda olduğundan ve çok küçük veya çok büyük olmadığından emin olun.

Performans ve Optimizasyon Notları

Handles sınıfı ve dolayısıyla Unity Handles.DrawLine metodu, yalnızca Unity Editör’ünde çalıştığı için oyununuzun çalışma zamanı performansını doğrudan etkilemez. Bu, istediğiniz kadar karmaşık Editör görselleştirmesi yapabileceğiniz anlamına gelir, çünkü bu çizimler derlenmiş oyununuzda yer almayacaktır.

Ancak, çok fazla Handles çizimi yapmak, Unity Editör’ünün kendisini yavaşlatabilir, özellikle karmaşık sahnelerde veya çok sayıda objeyi görselleştirirken. Bu nedenle, aşağıdaki optimizasyon notlarını göz önünde bulundurmakta fayda var:

  • Sadece Gerektiğinde Çizin: Mümkünse, çizimlerinizi yalnızca objenin seçili olduğu zamanlar veya belirli bir olay tetiklendiğinde yapın.
  • EventType.Repaint Kullanımı: OnSceneGUI() metodu her karede birden çok kez çağrılabilir. Performans için, çizim işlemlerini yalnızca Event.current.type == EventType.Repaint olduğunda gerçekleştirmek, gereksiz tekrarlanan çizim çağrılarını önleyebilir.
  • Aşırı Karmaşıklıktan Kaçının: Binlerce çizgi veya karmaşık geometriler çizmekten kaçının. Editör’ünüzün akıcılığını korumak için görselleştirmelerinizi optimize edin.

Sonuç

Unity Handles.DrawLine, Unity Editör’ünde görsel yardımcılar oluşturmak için son derece güçlü ve esnek bir araçtır. Özel Editör araçları geliştirmek, karmaşık oyun mantıklarını görselleştirmek veya hata ayıklama süreçlerini hızlandırmak için vazgeçilmez bir fonksiyondur. Bu makaledeki bilgiler ve ipuçları sayesinde, Unity geliştirme deneyiminizi bir üst seviyeye taşıyacak, daha anlaşılır ve yönetilebilir sahneler oluşturabileceksiniz. Unutmayın, iyi görselleştirme, hızlı ve verimli geliştirmenin anahtarlarından biridir.

Leave a Reply

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir