IEnumerator SomeCoroutine() {
Debug.Log("Doing a thing");
yield return null;
Debug.Log("Doing a thing on the next frame");
yield return new WaitForSeconds(2f);
Debug.Log("Doing a thing two seconds later!");
}
// in OnCollisionEnter:
StartCoroutine(SomeCoroutine());
BUT
You’re going to run into two problems:
an inactive or destroyed object can’t run coroutines, and you’re destroying the object you’re running this code on. Solution: Put this on a manager class instead, which watches the… uh… the “kolize”. When the kolize is null (when the object has been destroyed), it starts the coroutine.
You can’t instantiate a destroyed object, and you’re destroying the object before you instantiate it.
Solution: Make the object a prefab, instantiate that instead.
Got a problem in here. When I write IEnumerator SomeCoroutine, the code won’t make it threw yield return new WaitForSeconds(2f), it won’t even go threw yield return null.
Yeah, look…, debug messages me only - Doing a thing
using UnityEngine;
using System.Collections;
public class kolize : MonoBehaviour {
private float HP = 10f;
IEnumerator SomeCoroutine() {
Debug.Log("Doing a thing");
yield return null;
Debug.Log("Doing a thing on the next frame");
yield return new WaitForSeconds(2f);
Debug.Log("Doing a thing two seconds later!");
}
void OnCollisionEnter(Collision collision) {
Destroy(collision.gameObject);
HP -= promenneMaleRakety.damage;
if(HP <= 0)
{
StartCoroutine(SomeCoroutine());
Destroy(gameObject);
}
}
}
OK. A manager class basically means that there is a third-party overseer - it manages other objects without being affected itself. Most developers make a “GameRunner” or something like that. There’s nothing special about this object in the engine - it’s just an object with a script attached - it just serves special functions.
In this case, you want the manager class to watch the “kolize” object. You’ll have “public kolize currentKolize;” (Feel free to change the names as you see fit), and in the inspector, you drag in your kolize object from the scene. Now, we wait:
WaitThenRespawn is a coroutine that waits for 2 seconds, and then instantiates a prefab. When it does, you’ll have to make sure you re-assign currentKolize to the component on the newly spawned object.
There is one issue with this that I just noticed while typing it (but I’m leaving it here for the teaching opportunity): for those two seconds, currentKolize will still be null, so it will keep starting new WaitThenRespawn coroutines running in parallel… and after two seconds, the coroutines will all start to end and you’ll be flooded with new kolize’s. So, I’m going to tweak that concept a bit into a “game cycle” type coroutine:
void Start() {
StartCoroutine(GameCycle() );
}
public kolize currentKolize;
public GameObject kolizePrefab;
IEnumerator GameCycle () {
while (true) { //if you ever have this line, MAKE SURE you have a yield, return, or break in the body, or you WILL freeze Unity!
yield return null;
if (currentKolize == null) {
yield return new WaitForSeconds(2f);
GameObject spawn = Instantiate(kolizePrefab) as GameObject;
currentKolize = spawn.GetComponent<kolize>();
}
}
}
The GameCycle coroutine is a straightforward way to write simple processes that loop in a sequence. Unlike Update which’ll get called every frame no matter what, the coroutine will only be running one thing at a time. And if that thing involves waiting, then everything will wait.