2016-04-09 10 views
0

Ich habe ein Spielobjekt erstellt und es zu einem Prefab gemacht. Danach erstellte ich ein leeres Spielobjekt und fügte ein Skript bei, das das Fertighaus eine bestimmte Anzahl von Malen instanziiert und es einer Liste von Spielobjekten hinzufügt. Innerhalb desselben Skripts versuche ich zu erkennen, wenn ein bestimmtes Objekt in der Liste mit einem anderen Objekt des Tags "bronco" kollidiert ist und es zerstört. Bitte beachten Sie meine OnCollisionEnter2D Methode unter:OnCollisionEnter2D Methode im Skript die Instantiates Prefabs in Liste nicht erkannt

void OnCollisionEnter2D(Collision2D col) { 
    Debug.Log("entered collision method"); // not even logging 

    if (col.gameObject.tag == "bronco") { 

     int i = 0; 
     foreach(GameObject enemyToRemove in enemies) { 
      if (enemyToRemove == col.gameObject) { 
       Debug.Log(i); 
       Destroy(enemyToRemove, 0.1f); 

      } 

      i++; 
     } 
    } 
} 

Die erste Zeile des Codes in dem Verfahren wird ein Protokoll nicht gedruckt, obwohl ich eindeutig eine Kollision zwischen den genannten Aufgaben sehen. Beide Objekte haben Collider und einer hat starre Körper. Versuche ich auf die Listenelemente zuzugreifen oder die Kollision richtig einzustellen?

UPDATE

Ich erkannte ich einige weitere Details hinzuzufügen benötigt. Unten ist mein Skript, das an ein leeres Spielobjekt angehängt ist. Es verfügt über eine public-Eigenschaft zum Verknüpfen des Prefab im Inspector. Abgesehen von diesem Skript wird dem leeren Spielobjekt nichts anderes im Inspektor hinzugefügt. Ich habe keinen Trigger gesetzt, weil ich nicht möchte, dass die Objekte sich gegenseitig passieren. Wie kann ich meinen OnCollisionEnter2D Code funktionieren lassen und das genaue Element (Index) innerhalb der Liste erkennen, die mit dem Objekt mit dem Tag "bronco" in Kontakt gekommen ist?

using UnityEngine; 
using System.Collections; 
using System.Collections.Generic; 

public class SetupEnemies : MonoBehaviour { 


List<GameObject> enemies = new List<GameObject>(); 


public GameObject enemy; 
void Start() { 


    enemies = new List<GameObject>(); 

    int numberOfEnemies = 6; 
    Camera camera = GameObject.FindGameObjectWithTag ("MainCamera").GetComponent<Camera>(); 

    for (int i = 1; i < numberOfEnemies; i++) { 
     GameObject thisObject = (GameObject)Instantiate(enemy, new Vector3(Screen.width*i/4, Screen.height*i/2, camera.nearClipPlane), Quaternion.identity); 
     enemies.Add(thisObject); 
    } 

} 

void OnCollisionEnter2D(Collision2D col) { 
    Debug.Log("entered collision block"); 

    if (col.gameObject.tag == "bronco") { 

     int i = 0; 
     foreach(GameObject enemyToRemove in enemies) { 
      if (enemyToRemove == col.gameObject) { 
       Debug.Log(i); 
       Destroy(enemyToRemove, 0.1f); 

      } 

      i++; 
     } 
    } 
} 

// Update is called once per frame 
void Update() { 

    } 
} 
+0

nicht-kinematische Starrkörper nicht wahr? –

+0

@BurakKarasoy ja – Jickery

+0

Da Collider angefügt ist und es ist nicht kinematisch und ich weiß es nicht ... wählen Sie das Objekt, das Sie versuchen, in der Szene zu erkennen, dann machen Sie einen Screenshot und laden Sie es hier. Ich möchte sehen, welche anderen Dinge mit diesem Objekt verbunden sind. Es ist auch gut zu sehen, wie Sie das Spielobjekt bewegen. – Programmer

Antwort

1

OnCollisionEnter2D wird nur für das Objekt aufgerufen, das den Collider hat.

Kurz gesagt, Sie müssen OnCollisionEnter2D für das Objekt mit dem Collider haben, aber Sie können eine andere Methode in einem anderen Skript von Ihrem Objektskript aufrufen.

In Ihrer spezifischen Situation, das ist, was ich empfehle. Fügen Sie dem Prefab, das Sie instanziieren, ein Skript hinzu. Fügen Sie in diesem Skript Ihren OnCollisionEnter2D sowie eine öffentliche Variable für eine ID ein. Setzen Sie die öffentliche Variable bei der Instanziierung auf die Indexnummer.

Im Folgenden finden Sie Serviette Codierung, hoffentlich wird es kompilieren :)

Script auf feindlichen Generator:

using UnityEngine; 
using System.Collections; 
using System.Collections.Generic; 

public class SetupEnemies : MonoBehaviour { 


List<GameObject> enemies = new List<GameObject>(); 


public GameObject enemy; 
void Start() { 


    enemies = new List<GameObject>(); 

    int numberOfEnemies = 6; 
    Camera camera = GameObject.FindGameObjectWithTag ("MainCamera").GetComponent<Camera>(); 

    for (int i = 1; i < numberOfEnemies; i++) { 
     GameObject thisObject = (GameObject)Instantiate(enemy, new Vector3(Screen.width*i/4, Screen.height*i/2, camera.nearClipPlane), Quaternion.identity); 
     thisObject.GetComponent<Enemy>().id = i; 
     thisObject.GetComponent<Enemy>().enemySetterUpper = this; 
     enemies.Add(thisObject); 
    } 

} 

public void EnemyDestroyed(int enemyId) 
{ 
    Debug.Log(enemyId); 
    //Do whatever you want with enemies[enemyId] 
} 
} 

Script auf Fertig:

using UnityEngine; 
public class Enemy : MonoBehaviour { 


public int id; 
public SetupEnemies enemySetterUpper; 

void OnCollisionEnter2D(Collision2D col)  
{ 
    Debug.Log("entered collision block"); 

    if (col.gameObject.tag == "bronco") 
    { 
     enemySetterUpper.EnemyDestroyed(id); 
    } 
} 
} 
+0

Danke, es funktioniert, aber gibt es keinen Weg, wie ich auf sie zugreifen kann, um sie im gegnerischen Generatorskript zu zerstören? Meine Frage hat nur eine Liste, welche Handhabung auf diese Weise in Ordnung sein sollte, aber ich plane, sie zu erweitern, was bedeutet, mehrere komplexe Listen zu manipulieren. Ich halte diesen Ansatz in einem komplexeren Szenario für sehr umständlich und schwierig. Haben Sie Empfehlungen für einen komplexen Fall? – Jickery

+0

@Jickery Es klingt wie ein gutes Thema für einen Chat über Design. Es wäre schwierig, alles auf SO durchzuarbeiten. Ich würde mich freuen, es mit Ihnen zu besprechen, wenn Sie mir eine E-Mail schreiben wollen. Ich konnte keine Kontaktinformationen in deinem Profil sehen :) – Allen

+0

Vielen Dank. Ich habe gerade eine E-Mail gesendet. – Jickery