Kann ich zwei Kollisionsboxen auf demselben GameObject verwenden?

7

Ich habe zwei Kollisionsboxen auf demselben GameObject. Ich möchte nicht, dass die Kollisionsboxen Auslöser sind. Ich möchte die Kollisionsboxen auf dem eigentlichen GameObject haben, nicht seine Kinder.

Zum Beispiel, wenn ich nach einem Headshot suchen möchte. Mein Grund, keine Trigger zu wollen, ist, dass bereits ein Trigger verwendet wird. Mein Grund, keine Kinder zu wollen, ist die Sauberkeit. Ich verstehe, dass es Workarounds gibt. Ich habe mich gefragt, ob es einen direkteren Ansatz gibt.

Wie kann ich bei einer Kollision überprüfen, welche Kollisionsbox getroffen wurde?

Evorlor
quelle
Haben Sie die Kollision per Druck überprüft? Sie können einfach etwas im OnCollisionEnter-Block drucken ...
Shraddha Patel
Hallo. Kann ich wissen, warum Sie wissen müssen, welche Kollisionsbox getroffen wird?
xitnesscomplex
Sie benötigen nicht unbedingt mehrere Collider. Abhängig von Ihren Anforderungen kann die Aufgabe mit einem einzigen Collider ausgeführt werden. Können Sie weitere Details angeben?
SanSolo
Zum Beispiel, wenn ich nach einem Headshot suchen möchte. Mein Grund, keine Trigger zu wollen, ist, dass bereits ein Trigger verwendet wird. Mein Grund, keine Kinder zu wollen, ist die Sauberkeit. Ich verstehe, dass es Workarounds gibt. Ich habe mich gefragt, ob es einen direkteren Ansatz gibt.
Evorlor
Ich glaube nicht, dass es einen direkten Ansatz gibt. Ich denke daran, Distanz als Workaround zu bekommen.
xitnesscomplex

Antworten:

0

Ich kenne einen Weg, dies zu tun, wenn Sie Ihre Collider programmgesteuert erstellt haben. Siehe folgenden Quellcode:

using UnityEngine;
using System.Collections.Generic;

public class MultipleColliders : MonoBehaviour {

    //Enumeration to tell us what a collider is for
    enum ColliderType
    {
        Head,
        Body
    }

    //A quick lookup for our colliders associated with this gameobject
    Dictionary<Collider2D, ColliderType> Colliders;

    void Start () {
        InitColliders ();
    }

    //Programmatically create our colliders
    void InitColliders()
    {       
        Colliders = new Dictionary<Collider2D, ColliderType> ();

        BoxCollider2D boxCollider = transform.gameObject.AddComponent (typeof(BoxCollider2D)) as BoxCollider2D;
        boxCollider.offset = new Vector2 (0, -0.5f);
        boxCollider.size = new Vector3 (0.5f, 1f);
        Colliders.Add (boxCollider, ColliderType.Body);

        CircleCollider2D circleCollider = transform.gameObject.AddComponent (typeof(CircleCollider2D)) as CircleCollider2D;
        circleCollider.offset = new Vector2 (0, 0.5f);
        circleCollider.radius = 0.5f;
        Colliders.Add (circleCollider, ColliderType.Head);
    }

    //Check if our colliders were hit
    void Update () {

        //Raycast mouse cursor when pressed to simulate a hit for our example
        if (Input.GetMouseButtonDown (0)) {

            Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);            
            RaycastHit2D[] hit = Physics2D.RaycastAll (mousePosition, Vector2.zero);

            //lookup our hits to see what was hit
            for (int i = 0; i < hit.Length; i++)
            {
                if (Colliders.ContainsKey(hit[i].collider)) {
                    Debug.Log ( System.Enum.GetName( typeof(ColliderType), Colliders[hit[i].collider]) + " HIT!");              
                }
            }           
        }       
    }
}

Wenn Sie dies also auf diese Weise tun, erhalten Sie die von Ihnen angegebenen Anforderungen. Dadurch kann ein Spielobjekt mehrere Collider enthalten, ohne dass jedes ein untergeordnetes Objekt sein muss.

Es kann Ihnen auch sagen, welcher Collider getroffen wurde.

Lassen Sie mich wissen, wenn Sie Fragen zu dieser Implementierung haben.

jgallant
quelle
Danke, aber das programmgesteuerte Hinzufügen der Collider funktioniert bei mir nicht.
Evorlor
3
In diesem Fall sollten Sie untergeordnete Objekte verwenden. Andernfalls ist es sehr schwierig, jeden Collider voneinander zu unterscheiden. Eine andere Option könnte darin bestehen, die Collider-Klasse zu erweitern und eine eigene zu erstellen, in der Sie eine neue Eigenschaft hinzufügen können, um den Collider zu unterscheiden.
Jgallant
Hmmm ... Ich habe nie daran gedacht, die Collider-Komponente zu erweitern. Ist das möglich? Ich mag das.
Evorlor
2
Ja, dies ist jedoch nicht einfach, da Sie Collider2D erweitern müssen und keine vordefinierten Collider. Ich habe das noch nie persönlich gemacht, aber soweit ich das beurteilen kann, ist dies keine einfache Aufgabe.
Jgallant
0

Ich würde empfehlen, ein leeres Spielobjekt zu erstellen, das beide Spielobjekte für den gesamten Feind und ein zweites für den Kopf enthält. Dann könnten Sie einen Scheck schreiben, der auf der Kugel basiert, die sich mit dem Kopf schneidet, und von dort aus gehen.

using UnityEngine;
using System.Collections;

public Class BulletScript : MonoBehaviour {

public Transform bullet;
//tag as "Bullet"

void Start(){
  bullet = transform;
}

void OnTriggerEnter (Collider other){
   if (other.gameObject.CompareTag("Head"){
     Debug.Log("Headshot.");
   }

   if (other.gameObject.CompareTag("Enemy"){
      Debug.Log("Not a head shot.");
   }
 }
}
Tony Chacon
quelle
0

Wenn Sie nur ein GameObject für Ihren Charakter haben möchten, können Sie Ihrem GameObject nicht mehrere Collider desselben Typs hinzufügen und haben dennoch die Möglichkeit, auf alle in Ihren Skripten zuzugreifen (nur die ersten in der Reihenfolge der Komponenten sind verfügbar). Sie können jedoch mehrere Collider unterschiedlicher Typen hinzufügen, ohne die Zugänglichkeit zu beeinträchtigen. In Ihrem Fall können Sie CapsuleCollider oder BoxCollider für den Körper und einen SphereCollider für den Kopf hinzufügen. Das Skript für den Zugriff auf diese Collider lautet wie folgt:

using UnityEngine;
using System.Collections;

public class BulletScript : MonoBehaviour {

CapsuleCollider bodyCollider; //OR BoxCollider bodyCollider;
SphereCollider headCollider;

void Start () 
{
    bodyCollider = desiredGameObject.GetComponent<CapsuleCollider> (); //OR bodyCollider = gameObject.GetComponent<BoxCollider> ();
    headCollider = desiredGameObject.GetComponent<SphereCollider> ();
}

void OnTriggerEnter (Collider other)
{
    if (other == bodyCollider)
    {
        //This happens when the body is hit
    }
    if (other == headCollider)
    {
        //This happens when the head is hit
    }
}

Dieses Skript wird an Ihre Kugel angehängt (stellen Sie sicher, dass Sie auch einen Trigger Collider hinzufügen). Die OnTriggerEnter-Methode prüft, ob ein Collider in den Trigger Collider des Aufzählungszeichens eingegeben wurde. Die if-Anweisungen prüfen, welcher Collider den Trigger Collider eingegeben hat. Problem gelöst.

Lassen Sie mich wissen, wenn Sie Fragen oder Anregungen haben.

Sam R.
quelle
-1

Nach einigen Recherchen habe ich einen einfachen Weg gefunden, dies ohne Problemumgehungen zu tun.

Verwenden Sie beim Erstellen von Collidern jeweils unterschiedliche Namen wie Kopf, Rumpf, Beine, Arme. Bei der OnCollisionEnter-Methode mussten Sie lediglich alle Kontaktpunkte überprüfen.

void OnCollisionEnter(Collision col)
{
    foreach (ContactPoint contact in col.contacts)
    {
        Debug.Log(contact.thisCollider.name + " hit " + contact.otherCollider.name);

        if (contact.thisCollider.name == "HitBoxHead") {
            Debug.Log("Head Shot");
        }
    }
}
Jota Oliveira
quelle