Birlik: Bir üst komut dosyasından alt nesnede oluşan çakışma nasıl algılanır?


12

Bu yapı ile bir düşmanım var

  • Düşman
    • Vücut
      • baş
      • Sol Kol
      • Sağ kol

Ve bunun gibi.

Ayrıca vücudun her kısmı için bir çarpıştırıcı var. "Düşman" nesneme bir senaryo ekledim ve bu senaryoda beden, kafa, kol, sol vb. İçin olası çarpışmayı (kurşun) kesmek istiyorum.

Bunu yapmanın bir yolu var mı?

Yanıtlar:


16

Karakteri olan bir Rigidbody kullanıyorsanız, bunu kutudan çıkarabilirsiniz. :)

Yani hiyerarşiniz şöyle görünebilir:

  • Karakter (Rigidbody ve kontrol komut dosyası var)
    • çocuk (belki de çarpıştırıcıları vardır)
      • torun (belki de çarpıştırıcıları vardır)

OnCollisionEnter mesajları, Rigidbody'yi içeren GameObject üzerinde tetiklenecek ve her bir çarpıştırıcıya yapışmak için ekstra bir röle betiği yazmaya gerek kalmadan ana kontrol komut dosyanıza ulaşacaktır.

Çocuğunuzun çarpıştırıcılarından hangilerinin çarpışmaya karıştığını bulmanız gerekiyorsa, bunu şöyle yapabilirsiniz:

void OnCollisionEnter(Collision collision) {
    Collider myCollider = collision.contacts[0].thisCollider;
    // Now do whatever you need with myCollider.
    // (If multiple colliders were involved in the collision, 
    // you can find them all by iterating through the contacts)
}

5

Bunu çözmenin bir yolu iki senaryoya sahip olmak olacaktır: biri Düşman nesnesi için diğeri çocuk için (Düşman nesnesinin çocuklarına atamanız gerekir)

Üst komut dosyası

using UnityEngine;

 public class ParentScript : MonoBehaviour 
 {
     public void CollisionDetected(ChildScript childScript)
     {
         Debug.Log("child collided");
     } 
 }

Alt komut dosyası

using UnityEngine;

public class ChildScript : MonoBehaviour 
{
     void OnCollisionEnter(Collision collision)
     {
         transform.parent.GetComponent<ParentScript>().CollisionDetected(this);
     }
 }

Bu şekilde çocuğa bir çarpışma olduğunda bildirim almalısınız


2
Böyle bir çözüm kullanırsanız ve bu çarpışma çok gerçekleşirse, çocukların alıcı ebeveynlerinin GameObject'lerini önbelleğe almasını şiddetle tavsiye ederim. Aynı GetComponent'i çok fazla çağıracağınız her zaman iyi bir alışkanlıktır ve daha mantıklı olan "zincirin hangi ebeveyne gönderileceğini bulma" mantığının sadece bir kez olması gerekir. Ayrıca transform.parent sadece alacak unutmayın derhal ebeveyn.
Lunin

2

Üst nesneyi çocuklara iletebilir ve doğrudan üzerinde bir işlev çağırabilirsiniz. Bu, ebeveyn yayılımına güvenmeniz gerekmediğini garanti eder. Yani sonunda aptalca şeyler yapmıyorsuntransform.parent.parent

Ancak bu işlemi GetComponentInParent ile otomatikleştirebilirsiniz . Bu bulduğu ilk komut dosyasını alır. Ardından, önbellek nesnesindeki önbelleği, söz konusu önbelleğe alınan nesne üzerindeki işlevleri doğrudan çağırın.

Alternatif olarak, işlevleri alt nesneye bağlamak için UnityEvents (Mesajlar kullanmayın) kullanabilirsiniz. Birlik olayları ile herhangi bir keyfi dinleyici ekleyebilirsiniz, böylece sadece vurulmakta olan alt nesnenin üst düzey nesnesine bildirmekten daha fazlasını yapabilirsiniz.


1

Birlik Yanıtlarından doğrudan alıntı ( Ashish Dwivedi tarafından yazılmıştır ):

Çocuğa bir komut dosyası ekleyin ve içinde bir üst nesnenin komut dosyası referansı var. Şimdi ana komut dosyasında (OnCollisionEnter2DChild, OnCollisionStay2DChild, OnCollisionExit2DChild) gibi ana komut dosyasında 3 yöntem yazın ve çarpışma nesnesini geçirerek alt nesne komut dosyasında bulunan yöntemlerden (OnCollisionEnter2D, OnCollisionStay2D, OnCollisionExit2D) ilgili yöntem denir.


1

Çarpışma üzerinde bir kontrol gerçekleştirebilir ve hangi isabet kutusunun vurulduğunu görebilir ve gerekirse çarpma noktasını elde edebilirsiniz.

not: sabit gövde Çarpışma Kontrolü komut dosyasıyla aynı nesneye yerleştirilir.

Bu örnek, bir hedefe 'mermi' isabet hangi hitbox olduğunu görmek için kontrol ediyor.

private void OnCollisionEnter(Collision collision)
{                 
    if (collision.contacts[0].otherCollider.transform.gameObject.name == "HeadShot")                
       //DO STUFF            

    if (collision.contacts[0].otherCollider.transform.gameObject.name == "BodyShot")
       //DO STUFF    
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.