2017-12-07 23 views
0

Wie kann ich den Namen der Coroutine dynamisch machen? Ich benutze diese Ziele zu machen sterben automatisch nach wenigen Sekunden:Name der dynamischen Coroutine

void InitiateKill(int i) 
{ 
    //i is the number of the target 
    StartCoroutine(TargetDie(i, timeAlive/1000)); 
    //some other stuff 
} 

Wenn das Ziel, bevor dieser Timer Enden getötet, ich offensichtlich einen Fehler, weil es nicht noch einmal das Ziel töten.

Deshalb möchte ich die Coroutine dieses spezifischen Ziels stoppen, aber ich weiß nicht wie.

Ich habe versucht:

Coroutine b[i] = StartCoroutine(TargetDie(i, timeAlive/1000)); 

Aber das gibt einen Syntaxfehler. b[i] kann nicht für Coroutines verwendet werden.

Wie wird das richtig gemacht?

Update:

Dies ist (der relevante Teil) meine TargetDie Funktion:

IEnumerator TargetDie(int i, float delayTime) 
{ 
    yield return new WaitForSeconds(delayTime); 
    Destroy(targets[i]); 
} 

Wenn der Spieler das Ziel tötet, das tue ich:

void Damage(int i) 
{ 
    // at this time, the first Coroutine, started in InitiateKill, should stop, because otherwise it tries to destroy the target twice 
    StartCoroutine(TargetDie(i, 0)); 
} 
+0

Bewahren Sie die Nummer des Ziel irgendwo? Und wenn Sie möchten, dass es automatisch stoppt, können Sie dies in der TargetDie-Funktion selbst tun. Es lohnt sich zu erklären, was diese Funktion macht und wann sie stirbt/aufhören soll zu laufen. – Programmer

+0

Ja, in ihrem Namen: target0, target1, ... Wie ist das relevant für den Coroutineteil? – binoculars

+0

@Programmer: Ich habe meine Frage – binoculars

Antwort

0

Sie können einfach für null überprüfen, bevor es zu zerstören, so dass Sie keine Fehlermeldung erhalten:

if (targets != null) 
    Destroy(targets[i]); 

Aber unten ist die empfohlene Methode, wenn Sie wollen die alte Koroutine zu stoppen.


Sie können Dictionary verwenden, um damit umzugehen. Verwenden Sie die int i als Schlüssel und Coroutine als Wert.

Wenn Sie InitiateKill aufrufen, fügen Sie int i dem Wörterbuch hinzu, und wenn Sie die Coroutine starten, fügen Sie Coroutine als Wert im Wörterbuch hinzu.

Wenn Damage aufgerufen wird, überprüfen Sie, ob dieser int-Wert in Dictionary existiert. Wenn dies der Fall ist, verwenden Sie es, um den Wert Coroutine abzurufen und die alte Coroutine zu stoppen. Wenn es nicht beendet wird, starten Sie eine neue Coroutine und fügen Sie sie dann zu diesem Wörterbuch hinzu.

Das Wörterbuch sollte wie folgt aussehen:

Dictionary<int, Coroutine> dyingTarget = new Dictionary<int, Coroutine>(); 

Ihre neue InitiateKill Funktion, die auf die Dictionary fügt hinzu:

void InitiateKill(int i) 
{ 
    //i is the number of the target 
    Coroutine crt = StartCoroutine(TargetDie(i, timeAlive/1000)); 

    //Add to Dictionary 
    dyingTarget.Add(i, crt); 
} 

Ihre neue Damage Funktion prüft nun, wenn der Artikel bereits im Wörterbuch ist dann wiederholt es, stoppt die Coroutine und entfernt sie aus der Dictionary.

void Damage(int i) 
{ 
    // at this time, the first Coroutine, started in InitiateKill, should stop, because otherwise it tries to destroy the target twice 
    StopIfAlreadyRunning(i); 

    Coroutine crt = StartCoroutine(TargetDie(i, 0)); 
    //Add to Dictionary 
    dyingTarget.Add(i, crt); 
} 

void StopIfAlreadyRunning(int i) 
{ 
    Coroutine crtOut; 
    //Retrieve and stop old coroutine if it exist then removes it 
    if (dyingTarget.TryGetValue(i, out crtOut)) 
    { 
     StopCoroutine(crtOut); 
     dyingTarget.Remove(i); 
    } 
} 

Die neue TargetDie Funktion, die es nach der Tötung es aus den Dictionary entfernt. Es überprüft auch für null bevor es zu zerstören:

IEnumerator TargetDie(int i, float delayTime) 
{ 
    yield return new WaitForSeconds(delayTime); 
    if (targets != null) 
     Destroy(targets[i]); 
    //Remove from Dictionary 
    dyingTarget.Remove(i); 
} 
+1

Das ist genial, danke für die Antwort und Erklärung! – binoculars

+0

Froh, dass Sie meine Antwort hilfreich finden – Programmer

1

So sind die meisten Einfacher Weg, bewegen Sie die Coroutine auf das Objekt selbst.

Der Versuch, die Kontrolle über den Controller zu halten, bringt mehr Schmerzen als Lösung.

Sie könnten eine Liste von IEnumerator haben, um die laufenden Coroutinen zu verfolgen. Sie benötigen jedoch weiterhin eine Nachricht von dem Objekt, um den Controller darüber zu informieren, dass es tot ist. Sie vermissen diesen Teil. Sie benötigen ein Skript auf dem Ziel, damit der Controller diesen Typ kennt. Der Controller führt die Coroutine mit einem Verweis auf dieses Skript aus und fragt jeden Frame, an dem Sie sterben. Wenn das Ziel sterben soll, legt es einen Booleschen Wert zur Information fest. Die Verwendung von Destroy hält das Objekt bis zum Ende des Rahmens, so dass es funktionieren würde.

Aber das ist Doom später zu scheitern. Es ist irgendwie gegen das Programmierungskonzept, einen Controller zu haben, der alles macht. Sie sollten es eher als Bypass für Informationen sehen.