Hoy vamos a conocer en que consisten las “Corrutinas” en C# y Unity.
Las corrutinas son una de las características más prácticas y potentes que ofrece Unity para controlar la ejecución de código a lo largo del tiempo sin bloquear el juego. Si alguna vez has querido esperar unos segundos antes de que ocurra algo, hacer animaciones por código, o gestionar fases en un jefe final… las corrutinas son lo que necesitas 😀
Tutorial de Unity Nivel: Principiante.
4.1 ¿Qué es una Corrutina?
Una corrutina es un método especial en C# que puede pausar su ejecución y continuarla después de un tiempo o una condición. Esto se logra usando “IEnumerator” y “yield”. En otras palabras, una corrutina es como un proceso que puede dormirse y despertarse sin frenar el juego.
Ejemplo de Corrutina
Una Corrutina se crea usando el método tipo IEnumerator
IEnumerator MiCorrutina() { // Acción inicial Debug.Log("Inicia"); // Espera 3 segundos yield return new WaitForSeconds(3f); // Acción después de esperar Debug.Log("Pasaron 3 segundos"); }
Y se ejecuta desde algún otro método mediante el uso de “StartCoroutine()“
void Start() { StartCoroutine(MiCorrutina()); }
Se ve muy bien pero, ¿Por qué no usar Update() o Invoke?
- Update() corre cada frame: no es óptimo para tareas temporales o secuenciales.
- Invoke() es útil para mandar llamar a otros métodos pero es muy limitado (no puedes usar condiciones ni bucles complejos).
- Las corrutinas son más flexibles y controlables.
4.2 Deteniendo Corrutinas
Una de las grandes ventajas de usar Corrutinas, es que “las puedes mandar detener“
Y esto se puede lograr usando StopCoroutine( ) para detener una corrutina en específico o StopAllCoroutines( ) para detener todas las corrutinas que se estén ejecutando en tu script.
4.3 Ejemplos de Corrutinas
Ejemplo 1: Temporizador simple
public class Temporizador : MonoBehaviour { void Start() { StartCoroutine(TemporizadorDeInicio()); } IEnumerator TemporizadorDeInicio() { Debug.Log("El juego inicia en..."); yield return new WaitForSeconds(1); Debug.Log("3"); yield return new WaitForSeconds(1); Debug.Log("2"); yield return new WaitForSeconds(1); Debug.Log("1"); Debug.Log("¡Acción!"); } }
Ejemplo 2: Movimiento suave con corrutina
public class MoverObjeto : MonoBehaviour { public Transform destino; public float duracion = 2f; void Start() { StartCoroutine(MoverSuavemente(transform, destino.position, duracion)); } IEnumerator MoverSuavemente(Transform obj, Vector3 destino, float tiempo) { Vector3 inicio = obj.position; float tiempoTranscurrido = 0f; while (tiempoTranscurrido < tiempo) { obj.position = Vector3.Lerp(inicio, destino, tiempoTranscurrido / tiempo); tiempoTranscurrido += Time.deltaTime; yield return null; // espera un frame } obj.position = destino; // asegura que llega al final } }
Este ejemplo interpola suavemente entre dos posiciones durante 2 segundos.
Ejemplo 3: Esperar a que el jugador esté cerca
public class EsperarJugador : MonoBehaviour { public Transform jugador; public float rango = 3f; void Start() { StartCoroutine(EsperarCercania()); } IEnumerator EsperarCercania() { yield return new WaitUntil(() => Vector3.Distance(transform.position, jugador.position) < rango); Debug.Log("¡Jugador en rango! Activar enemigo."); } }
Ejemplo 4: Spawner con corrutinas
public class Spawner : MonoBehaviour { public GameObject enemigoPrefab; void Start() { StartCoroutine(SpawnEnemigos()); } IEnumerator SpawnEnemigos() { while (true) { Instantiate(enemigoPrefab, transform.position, Quaternion.identity); yield return new WaitForSeconds(2f); // spawnea cada 2 segundos } } }
4.4 Conclusión
Las corrutinas son una de las herramientas más útiles de Unity para gestionar tiempo y secuencias de ejecución sin complicarte la vida con programación multihilo. Bien usadas, son clave para:
- Controlar animaciones y movimientos
- Diseñar lógica por fases
- Evitar código desorganizado en Update()
Es importante saber lo siguiente:
- Las corrutinas no son hilos reales (threads). No bloquean la ejecución pero siguen corriendo dentro del hilo principal.
- Si destruyes el GameObject o el MonoBehaviour, la corrutina se detiene automáticamente.
- No puedes usar yield return en métodos normales, solo en IEnumerator.
- Evita abusar (muchas corrutinas mal gestionadas pueden afectar el rendimiento)
Los tipos de espera “yield” que puedes usar en una corrutina son:
Instrucción | Significado |
---|---|
yield return null; |
Espera un frame |
yield return new WaitForSeconds(t); |
Espera t segundos reales |
yield return new WaitForSecondsRealtime(t); |
Igual que arriba, pero sin ser afectado por Time.timeScale |
yield return new WaitUntil(() => condición); |
Espera hasta que la condición sea verdadera |
yield return new WaitWhile(() => condición); |
Espera mientras la condición sea verdadera |
¿Cuándo usar Corrutinas?
Corrutina Ideal Para: | Alternativa |
---|---|
Temporizadores | Invoke , Update + Time.time |
Esperar condiciones | Update + if |
Animaciones por código | Lerp en Update , pero más limpio con corrutinas |
Spawners | Muy común |
Fases de jefes | Excelente para controlar secuencias |
Secuencias narrativas | Ideal |
Ejercicios.
Para reforzar lo aprendido, es necesario practicarlo, por ello intenta realizar los siguientes ejercicios:
- Diseña tu propia corrutina que incremente el valor de una variable en 1 cada 5 segundos; pero que al llegar al valor de 4 se detenga.
Este Tutorial de Unity termina aquí. Acompáñanos en el siguiente tutorial donde veremos “Delegados y Eventos”.
Siguiente Tutorial de Unity: “5. Delegados y Eventos“
Unity Tutorial: “C# en Unity 2“
1. Los Métodos Clave de Unity
2. Herencia
3. Encapsulamiento y Constructores
4. Corrutinas en Unity
5. Delegados y Eventos
6. GameManager y Control de Flujo
7. ScriptableObjects en Unity
8. El Patrón Factory
9. Máquinas de Estado en Unity
10. Gestionando nuestro Código
Ver más Tutoriales