Unity: bagaimana mendeteksi tabrakan yang terjadi pada objek anak, dari skrip induk?


12

Saya punya musuh, dengan struktur ini

  • Musuh
    • Tubuh
      • Kepala
      • Lengan Kiri
      • Lengan kanan

Dan seterusnya.

Saya juga punya collider untuk setiap bagian tubuh. Dalam objek "Musuh" saya telah melampirkan skrip dan dalam skrip itu saya ingin mencegat kemungkinan tabrakan (peluru) untuk tubuh, kepala, lengan, kiri dll.

Apakah ada cara untuk melakukan ini?

Jawaban:


16

Jika Anda menggunakan benda tegar dengan karakter, Anda bisa mengeluarkannya dari kotak. :)

Jadi hierarki Anda bisa terlihat seperti ini:

  • Karakter (memiliki naskah kaku dan skrip kontrol)
    • anak (mungkin memiliki colliders)
      • cucu (mungkin memiliki colliders)

Pesan OnCollisionEnter akan diaktifkan pada GameObject yang berisi Rigidbody, mencapai skrip kontrol orang tua Anda tanpa perlu menulis skrip relay tambahan untuk menempel pada masing-masing collider.

Jika Anda perlu mencari tahu anak yang bertabrakan dengan Anda yang terlibat dalam tabrakan, Anda dapat melakukannya seperti ini:

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

Salah satu cara untuk menyelesaikannya adalah dengan memiliki dua skrip: satu untuk objek Musuh dan satu lagi untuk anak (yang harus Anda tetapkan untuk anak-anak dari objek Musuh)

Script induk

using UnityEngine;

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

Naskah anak

using UnityEngine;

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

Dengan cara ini Anda harus diberi tahu setiap kali tabrakan terjadi pada seorang anak


2
Jika Anda menggunakan solusi seperti ini dan tabrakan ini sering terjadi, saya sangat menyarankan agar anak-anak men-cache GameObject orangtua mereka. Ini adalah kebiasaan yang baik setiap kali Anda akan memanggil banyak GetComponent yang sama dan memungkinkan Anda untuk membuat salah satu dari yang lebih rumit "menemukan induk mana yang akan dikirim ke" logika hanya perlu terjadi sekali. Juga ingat transform itu . Orang tua hanya akan mendapatkan orang tua langsung .
Lunin

2

Anda dapat dengan mudah memberikan objek teratas kepada anak-anak dan memanggil fungsi langsung di atasnya. Ini menjamin bahwa Anda tidak harus bergantung pada propagasi orang tua. Jadi Anda tidak berakhir melakukan hal-hal konyol sepertitransform.parent.parent

Namun Anda bisa mengotomatiskan proses ini dengan GetComponentInParent . Ini mengambil skrip pertama yang ditemukannya. Kemudian cache itu di objek tabrakan Anda, langsung memanggil fungsi pada objek yang di-cache.

Atau Anda dapat menggunakan UnityEvents (jangan gunakan Pesan) untuk mengikat fungsi ke objek anak. Dengan acara persatuan, Anda dapat menambahkan pendengar yang sewenang-wenang sehingga Anda dapat melakukan lebih dari sekadar memberi tahu objek tingkat atas dari objek anak yang dipukul.


1

Kutipan langsung dari Unity Answers (ditulis oleh Ashish Dwivedi ):

Tambahkan skrip ke child dan di dalamnya ada referensi skrip objek induk. Sekarang tulis 3 metode dalam skrip induk seperti (OnCollisionEnter2DChild, OnCollisionStay2DChild, OnCollisionExit2DChild) dan memanggil masing-masing metode dari metode (OnCollisionEnter2D, OnCollisionStay2D, OnCollisionExit2D) yang ada di skrip objek anak dengan melewatkan objek collision.


1

Anda dapat melakukan pemeriksaan pada tabrakan dan melihat kotak hit mana yang terkena dan juga mendapatkan titik dampak jika diperlukan.

catatan: benda tegar ditempatkan pada objek yang sama yang memiliki skrip Collision Check.

Contoh ini memeriksa untuk melihat hitbox mana yang 'proyektil' mengenai target.

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    
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.