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

Unity'de OnCollisionEnter() Kullanımı: Çarpışma Anını Yakala

Paylaşan: Unity Eğitim 27 October 2025 7 dakika okuma 82 görüntülenme

Unity oyun geliştirmede, fizik tabanlı etkileşimler oyun deneyiminin temelini oluşturur. Karakterlerin zeminle teması, mermilerin düşmanlara isabet etmesi veya toplanabilir öğelerin oyuncu tarafından alınması gibi durumlar, çarpışma (collision) tespiti ile yönetilir. Bu etkileşimleri yakalamak için Unity, `OnCollisionEnter()` adında güçlü bir geri çağırım (callback) metodu sunar. Bu makalede, Unity OnCollisionEnter metodunun nasıl kullanılacağını, temel prensiplerini, pratik ipuçlarını ve yaygın hataları ayrıntılı bir şekilde inceleyeceğiz.

Unity OnCollisionEnter() Nedir?

OnCollisionEnter(), Unity'de iki fiziksel obje birbirine çarptığı anda, yani çarpışma başladığı zaman çağrılan özel bir metottur. Bu metot, genellikle bir MonoBehaviour sınıfından türetilmiş bir script'in içinde tanımlanır ve çarpışan objelerle ilgili bilgilere erişim sağlar. Örneğin, bir topun duvara çarpıp ses çıkarması veya bir düşmanın hasar alması gibi anlık tepkileri bu metot sayesinde programlayabiliriz.

Temel Gereksinimler

OnCollisionEnter() metodunun doğru çalışabilmesi için bazı ön koşullar vardır:

  1. Collider Bileşeni: Çarpışacak her iki objede de birer Collider bileşeni bulunmalıdır (örn: BoxCollider, SphereCollider, CapsuleCollider). Bu Collider'ların Is Trigger özelliği işaretli olmamalıdır. Eğer işaretli olursa, çarpışma yerine tetikleyici (trigger) olayı gerçekleşir ve OnTriggerEnter() metodu çağrılır.
  2. Rigidbody Bileşeni: Çarpışan objelerden en az birinde bir Rigidbody bileşeni bulunmalıdır. Rigidbody, objenin fiziksel hareketini (yerçekimi, kuvvetler vb.) yöneten bileşendir. Genellikle hareket eden objeye Rigidbody eklenir, ancak statik bir objenin (örn: zemin) Collider'ı varsa ve hareket eden objenin Rigidbody'si varsa da çarpışma tespiti gerçekleşir.

OnCollisionEnter() Metodunun Yapısı

OnCollisionEnter() metodu, çarpışma hakkında bilgi içeren bir Collision objesi alır:

void OnCollisionEnter(Collision collision)
{
    // Çarpışma başladığında burada kod çalışır.
    Debug.Log("Çarpışma Algılandı: " + collision.gameObject.name);
}

Collision objesi, çarpışma anı hakkında çok değerli bilgiler içerir:

  • collision.gameObject: Çarpan diğer objenin GameObject'i.
  • collision.collider: Çarpan diğer objenin Collider'ı.
  • collision.contacts: Çarpışmanın gerçekleştiği temas noktaları dizisi. Her ContactPoint, pozisyon ve normal vektör gibi bilgiler içerir.
  • collision.relativeVelocity: Çarpışma anında iki Rigidbody arasındaki göreceli hız.

Unity OnCollisionEnter Kullanımı: Detaylı İnceleme

Farklı Objelerle Çarpışmayı Ayırt Etme

Oyunlarınızda farklı türde objelerle çarpışmaları farklı şekillerde ele almanız gerekebilir. Bunu yapmanın en yaygın yolları etiketler (Tags) ve katmanlar (Layers) kullanmaktır.

Etiket (Tag) Kullanımı

Her GameObject'in bir etiketi olabilir. Bu etiketleri kullanarak belirli objelerle olan çarpışmaları filtreleyebilirsiniz:

void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.CompareTag("Düşman"))
    {
        Debug.Log("Düşmana çarptı!");
        // Düşmana hasar verme, ses çalma vb.
    }
    else if (collision.gameObject.CompareTag("Zemin"))
    {
        Debug.Log("Zemine çarptı!");
        // Yere düşme animasyonu, zıplama sesi vb.
    }
}

CompareTag() metodu, gameObject.tag == "Düşman" kullanmaktan daha performanslıdır çünkü string karşılaştırması yerine dahili bir hash değeri kullanır.

Katman (Layer) Kullanımı

Unity'nin Fizik Ayarları'nda (Edit > Project Settings > Physics) hangi katmanların birbiriyle çarpışacağını belirleyebilirsiniz. Bu, belirli çarpışmaları tamamen engellemek veya sadece belirli katmanlar arasındaki çarpışmaları kontrol etmek için idealdir. Örneğin, 'Oyuncu' katmanının 'DüşmanMermisi' katmanıyla çarpışmasını sağlayıp, 'OyuncuMermisi' katmanıyla çarpışmasını engelleyebilirsiniz.

OnCollisionEnter, OnCollisionStay ve OnCollisionExit Farkları

OnCollisionEnter() sadece çarpışmanın başladığı tek karede çağrılırken, Unity'de çarpışma ile ilgili başka geri çağırım metotları da bulunur:

  • OnCollisionStay(Collision collision): İki obje birbirine temas etmeye devam ettiği her karede çağrılır. Sürekli temas gerektiren durumlar için (örn: objeyi itme) kullanışlıdır.
  • OnCollisionExit(Collision collision): İki obje arasındaki çarpışma sona erdiği tek karede çağrılır. Temasın kesildiği anı yakalamak için kullanılır.

Pratik İpuçları

  1. Performans İçin CompareTag() Kullanın: Yukarıda belirtildiği gibi, etiket karşılaştırmaları için her zaman collision.gameObject.CompareTag("EtiketAdı") kullanın. Bu, direkt string karşılaştırmasına göre daha hızlıdır ve olası yazım hatalarını da azaltır.
    // İyi
    if (collision.gameObject.CompareTag("Player"))
    {
        // ...
    }
    
    // Kötü (daha yavaş)
    if (collision.gameObject.tag == "Player")
    {
        // ...
    }
  2. Fizik Katmanlarını Akıllıca Kullanın: Gereksiz çarpışma kontrollerinden kaçınmak için Unity OnCollisionEnter metodunu kullanmadan önce Physics Layer Collision Matrix'i (Proje Ayarları > Fizik) ayarlayın. Bu, belirli katmanlar arasındaki çarpışmaları tamamen devre dışı bırakarak hem performansı artırır hem de kod karmaşıklığını azaltır.
  3. Sadece Bir Kere İşlem Yapın: Eğer bir çarpışma sonucunda sadece bir kere gerçekleşmesi gereken bir olay varsa (örn: merminin yok olması), bu olayı OnCollisionEnter() içinde tetikleyin ve ardından objeyi imha edin veya devre dışı bırakın. Aksi takdirde, OnCollisionStay() veya yanlış mantık yüzünden aynı olay birden çok kez tetiklenebilir.
    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Düşman"))
        {
            // Düşmana hasar ver
            collision.gameObject.GetComponent<DüşmanSağlığı>()?.HasarAl(10);
            // Mermiyi yok et
            Destroy(gameObject);
        }
    }

Yaygın Hatalar ve Çözümleri

1. Rigidbody Eksikliği

Hata: OnCollisionEnter() metodu asla çağrılmıyor.

Çözüm: Çarpışan objelerden en az birinde bir Rigidbody bileşeni olduğundan emin olun. Genellikle hareket eden objeye eklenir.

2. Collider'ın 'Is Trigger' Olarak Ayarlanması

Hata: OnCollisionEnter() yerine OnTriggerEnter() çağrılıyor.

Çözüm: Çarpışma tespiti için Collider bileşeninin Is Trigger özelliğinin işaretli olmadığından emin olun. Eğer sadece temas tespiti ve fiziksel tepki olmaması isteniyorsa OnTriggerEnter() kullanın.

3. Yanlış Obje Kontrolü

Hata: Her çarpışmada aynı kod çalışıyor, istenmeyen etkileşimler oluyor.

Çözüm: collision.gameObject.CompareTag() veya collision.gameObject.layer kullanarak çarpışan diğer objeyi doğru bir şekilde ayırt edin ve sadece ilgili objelerle etkileşim kurun.

4. Null Reference Exception

Hata: GetComponent() çağrısı sırasında obje bulunamadığında hata alınması.

Çözüm: Bir bileşene erişmeden önce, o bileşenin çarpışan objede var olup olmadığını kontrol edin. C# 6.0 ve sonrası için null koşullu operatör (?.) kullanışlıdır:

void OnCollisionEnter(Collision collision)
{
    DüşmanSağlığı düşman = collision.gameObject.GetComponent<DüşmanSağlığı>();
    if (düşman != null)
    {
        düşman.HasarAl(10);
    }
    // Veya daha kısaca:
    collision.gameObject.GetComponent<DüşmanSağlığı>()?.HasarAl(10);
}

Performans ve Optimizasyon Notları

  • Layer Collision Matrix: En etkili performans optimizasyonlarından biri, Physics Layer Collision Matrix'i (Proje Ayarları > Fizik) kullanarak gereksiz çarpışma kontrollerini tamamen kapatmaktır. Bu, Unity'nin çarpışma algılama motorunun daha az iş yapmasını sağlar.
  • Ağır İşlemlerden Kaçının: Özellikle OnCollisionStay() içinde sıkça çağrılan metotlarda, performansı düşürecek ağır hesaplamalardan (örn: karmaşık matematiksel işlemler, büyük veri yapılarını yineleme) kaçının. OnCollisionEnter() ise genellikle bir kere çağrıldığı için daha esnektir, ancak yine de aşırı yüklenmemelidir.
  • GetComponent() Çağrılarını Optimize Edin: Eğer bir çarpışma objesinden sıkça bir bileşene erişmeniz gerekiyorsa, bu bileşeni bir referansa kaydedip tekrar tekrar GetComponent() çağırmaktan kaçının. Özellikle OnCollisionStay() içinde her karede GetComponent() çağırmak performansı düşürebilir. OnCollisionEnter() içinde bir kere alıp sonraki karelerde kullanmak daha iyidir.

Unity OnCollisionEnter metodu, fizik tabanlı oyunlarınızda objeler arası etkileşimleri yönetmek için vazgeçilmez bir araçtır. Bu makaledeki bilgileri kullanarak, oyunlarınızda daha dinamik ve gerçekçi çarpışma tepkileri oluşturabilir, yaygın hatalardan kaçınabilir ve performanslı çözümler üretebilirsiniz. Unutmayın, pratik yapmak ve farklı senaryoları denemek, bu konudaki ustalığınızı artıracaktır!

🧠 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!