Einheit: Wie erkennt man eine Kollision, die auf einem untergeordneten Objekt auftritt, anhand eines übergeordneten Skripts?

12

Ich habe einen Feind mit dieser Struktur

  • Feind
    • Körper
      • Kopf
      • Arm links
      • Arm rechts

Und so weiter.

Ich habe auch einen Collider für jeden Körperteil. In meinem "Enemy" -Objekt habe ich ein Skript angehängt und in diesem Skript möchte ich mögliche Kollisionen (eine Kugel) für Körper, Kopf, Arm, links usw. abfangen.

Gibt es eine Möglichkeit, dies zu tun?

stighy
quelle

Antworten:

16

Wenn Sie einen starren Körper mit dem Charakter verwenden, können Sie diesen sofort einsatzbereit machen. :) :)

Ihre Hierarchie könnte also so aussehen:

  • Charakter (hat Rigidbody und Kontrollskript)
    • Kind (hat vielleicht Collider)
      • Enkel (hat vielleicht Collider)

OnCollisionEnter-Nachrichten werden auf dem GameObject mit dem Rigidbody ausgelöst und erreichen Ihr übergeordnetes Steuerungsskript, ohne dass Sie ein zusätzliches Relay-Skript schreiben müssen, um auf jedem Collider zu bleiben.

Wenn Sie herausfinden möchten, welcher der Kollider Ihres Kindes an der Kollision beteiligt war, können Sie dies folgendermaßen tun:

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)
}
DMGregory
quelle
5

Eine Möglichkeit, dies zu lösen, besteht darin, zwei Skripte zu haben: eines für das Enemy-Objekt und eines für das Kind (das Sie den Kindern des Enemy-Objekts zuweisen müssen).

Übergeordnetes Skript

using UnityEngine;

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

Untergeordnetes Skript

using UnityEngine;

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

Auf diese Weise sollten Sie benachrichtigt werden, wenn ein Kind eine Kollision erleidet


quelle
2
Wenn Sie eine solche Lösung verwenden und diese Kollision häufig auftritt, empfehle ich dringend, dass die Kinder das GameObject ihrer empfangenden Eltern zwischenspeichern. Es ist eine gute Angewohnheit, wenn Sie dieselbe GetComponent häufig aufrufen, und ermöglicht es Ihnen, die schwierigere Logik "Finden, an welche Eltern in der Kette gesendet werden soll" nur einmal auszuführen. Denken Sie auch daran, dass transform.parent nur das unmittelbare übergeordnete Element erhält .
Lunin
2

Sie können das oberste Objekt einfach an die untergeordneten Objekte übergeben und eine Funktion direkt darauf aufrufen. Dies garantiert, dass Sie sich nicht auf die Weitergabe durch Eltern verlassen müssen. Sie machen also keine dummen Dinge wietransform.parent.parent

Sie können diesen Prozess jedoch mit automatisieren GetComponentInParent . Dadurch wird das erste gefundene Skript abgerufen. Speichern Sie dann das Cache in Ihrem Kollisionsobjekt und rufen Sie direkt Funktionen für das zwischengespeicherte Objekt auf.

Alternativ können Sie UnityEvents verwenden (keine Nachrichten verwenden), um Funktionen an das untergeordnete Objekt zu binden. Mit Unity-Ereignissen können Sie einen beliebigen Listener hinzufügen, sodass Sie mehr tun können, als nur das Objekt der obersten Ebene über das getroffene untergeordnete Objekt zu benachrichtigen.

Sidar
quelle
1

Direktes Zitat aus Unity Answers (geschrieben von Ashish Dwivedi ):

Fügen Sie dem untergeordneten Element ein Skript hinzu, und darin befindet sich eine Skriptreferenz des übergeordneten Objekts. Schreiben Sie nun 3 Methoden in ein übergeordnetes Skript wie (OnCollisionEnter2DChild, OnCollisionStay2DChild, OnCollisionExit2DChild) und rufen Sie die entsprechende Methode aus den Methoden (OnCollisionEnter2D, OnCollisionStay2D, OnCollisionExit2D) auf, die sich im untergeordneten Objektskript befinden, indem Sie das Kollisionsobjekt übergeben.

S. Tarık Çetin
quelle
1

Sie können die Kollision überprüfen und feststellen, welches Trefferfeld getroffen wurde, und bei Bedarf auch den Aufprallpunkt ermitteln.

Hinweis: Der starre Körper befindet sich auf demselben Objekt wie das Collision Check-Skript.

In diesem Beispiel wird überprüft, welche Trefferbox das 'Projektil' auf ein Ziel getroffen hat.

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    
}
Justin Markwell
quelle