Unity: come rilevare la collisione che si verifica su un oggetto figlio, da uno script principale?


12

Ho un nemico, con questa struttura

  • Nemico
    • Corpo
      • Capo
      • Braccio sinistro
      • Braccio destro

E così via.

Ho anche un collider per ogni parte del corpo. Nel mio oggetto "Enemy" ho allegato una sceneggiatura e in quella sceneggiatura vorrei intercettare una possibile collisione (un proiettile) per corpo, testa, braccio, sinistra ecc.

C'è un modo per fare questo?

Risposte:


16

Se stai usando un Rigidbody con il personaggio, puoi tirarlo fuori dalla scatola. :)

Quindi la tua gerarchia potrebbe apparire così:

  • Personaggio (ha Rigidbody e script di controllo)
    • bambino (forse ha collider)
      • nipote (forse ha collider)

I messaggi di OnCollisionEnter si attiveranno sull'oggetto GameObject contenente il Rigidbody, raggiungendo lo script di controllo principale senza la necessità di scrivere uno script di inoltro aggiuntivo da applicare su ciascun collider.

Se hai bisogno di scoprire quale dei tuoi collider minori è stato coinvolto nella collisione, puoi farlo in questo modo:

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

Un modo per risolverlo sarebbe avere due script: uno per l'oggetto Enemy e un altro per il bambino (che devi assegnare ai bambini dell'obj Enemy)

Script principale

using UnityEngine;

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

Sceneggiatura per bambini

using UnityEngine;

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

In questo modo dovresti ricevere una notifica ogni volta che si verifica una collisione a un bambino


2
Se usi una soluzione come questa e queste collisioni si verificano molto, ti consiglio vivamente di lasciare in cache i GameObject dei genitori che li ricevono. È una buona abitudine ogni volta che chiamerai spesso lo stesso GetComponent e ti consente di fare una delle "scoperte più complicate sulla catena da inviare alla logica" solo una volta. Ricorda inoltre che transform.parent otterrà solo il genitore immediato .
Lunin,

2

Puoi semplicemente passare l'oggetto superiore ai bambini e chiamare una funzione direttamente su di esso. Questo garantisce che non devi fare affidamento sulla propagazione dei genitori. Quindi non finisci per fare cose stupide cometransform.parent.parent

Tuttavia, è possibile automatizzare questo processo con GetComponentInParent . Questo recupera il primo script che trova. Quindi memorizzalo nella cache dell'oggetto di collisione, chiama direttamente le funzioni su detto oggetto memorizzato nella cache.

In alternativa, è possibile utilizzare UnityEvents (non utilizzare Messaggi) per associare le funzioni all'oggetto figlio. Con gli eventi di unità puoi aggiungere qualsiasi ascoltatore arbitrario in modo da poter fare qualcosa in più della semplice notifica dell'oggetto di livello superiore dell'oggetto figlio colpito.


1

Citazione diretta da Unity Answers (scritta da Ashish Dwivedi ):

Aggiungi uno script a figlio e al suo interno ha un riferimento di script dell'oggetto padre. Ora scrivi 3 metodi nello script principale come (OnCollisionEnter2DChild, OnCollisionStay2DChild, OnCollisionExit2DChild) e chiamato il rispettivo metodo dai metodi (OnCollisionEnter2D, OnCollisionStay2D, OnCollisionExit2D) che si trovano nello script dell'oggetto figlio passando l'oggetto collisione.


1

È possibile eseguire un controllo sulla collisione e vedere quale hit box è stato colpito e anche ottenere il punto di impatto, se necessario.

nota: il corpo rigido viene posizionato sullo stesso oggetto che ha lo script Controllo collisione.

Questo esempio sta controllando per vedere quale hitbox ha colpito il 'proiettile' su un bersaglio.

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    
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.