Qué es el ciclo de vida#
Cuando escribes un script en Unity, tu clase hereda de MonoBehaviour. Eso te da un superpoder: Unity llama automáticamente a ciertos métodos tuyos en momentos concretos, siempre en el mismo orden. Tú no los llamas nunca; los llama el motor.
A esos métodos se les llama event functions o "métodos del ciclo de vida". Entender cuándo se ejecuta cada uno es, probablemente, el conocimiento que más bugs te va a ahorrar en Unity.
No programas un bucle principal como en otros lenguajes. Escribes reacciones a momentos (Start, Update…) y Unity las orquesta por ti.
Cómo funciona#
Cada fotograma (frame), Unity recorre todos los objetos activos de la escena y, para cada script, llama a los métodos que tenga definidos. Si tu script no define Update, Unity simplemente no lo llama: no hay penalización por métodos que no existen.
Hay tres grandes grupos:
- Inicialización — se ejecutan una vez:
Awake,OnEnable,Start. - Bucle de juego — se ejecutan repetidamente:
FixedUpdate,Update,LateUpdate. - Fin de vida — al desactivar o destruir:
OnDisable,OnDestroy.
El orden completo#
Este es el orden real en el que Unity invoca los métodos más habituales:
| Método | Cuándo se ejecuta | Uso típico |
|---|---|---|
Awake() | Una vez, al cargar el objeto (aunque esté desactivado el script) | Cachear referencias propias (GetComponent) |
OnEnable() | Cada vez que el objeto/script se activa | Suscribirse a eventos |
Start() | Una vez, antes del primer Update, solo si está activo | Estado inicial que depende de otros objetos |
FixedUpdate() | A intervalos fijos (0,02 s por defecto) | Física: Rigidbody, fuerzas |
Update() | Una vez por fotograma | Input, lógica de juego |
LateUpdate() | Cada fotograma, después de todos los Update | Cámara que sigue al jugador |
OnDisable() | Al desactivar el objeto/script | Darse de baja de eventos |
OnDestroy() | Al destruir el objeto | Liberar recursos |
Usa Awake para preparar lo tuyo (obtener tus componentes) y Start para lo que dependa de otros objetos. ¿Por qué? Porque cuando se ejecuta tu Start, ya se han ejecutado todos los Awake de la escena, así que puedes fiarte de que los demás objetos están inicializados.
Ejemplo básico#
using UnityEngine;
public class Jugador : MonoBehaviour
{
private Rigidbody rb;
void Awake()
{
// Lo mío: cacheo mi propio Rigidbody
rb = GetComponent<Rigidbody>();
}
void Start()
{
// Depende de otros: el GameManager ya existe seguro
GameManager.Instance.RegistrarJugador(this);
}
void Update()
{
// Input: cada fotograma
if (Input.GetKeyDown(KeyCode.Space))
Debug.Log("Salto solicitado");
}
void FixedUpdate()
{
// Física: a ritmo fijo
rb.AddForce(Vector3.forward * 10f);
}
}Por qué Update no sirve para física#
Ver el artículo dedicado: Update vs FixedUpdate. En resumen: Update corre a los FPS del jugador (variables), y la física necesita pasos de tiempo constantes para ser estable y reproducible. Por eso todo lo que toque un Rigidbody va en FixedUpdate.
Cómo funciona por dentro#
Podrías pensar en usar el constructor de la clase para inicializar. No lo hagas. Unity crea los objetos por su cuenta (a veces en hilos distintos, al deserializar), y en ese momento el objeto todavía no está "conectado" al motor: transform, gameObject o GetComponent pueden no estar listos. Por eso Unity te ofrece Awake: es su equivalente seguro al constructor, llamado cuando el objeto ya está integrado en la escena. Escribir lógica en el constructor de un MonoBehaviour produce comportamientos impredecibles y advertencias del editor.
Errores frecuentes#
- Cachear en
Update: llamar aGetComponentcada fotograma es caro. Hazlo una vez enAwake. - Suscribirte a eventos en
Awakey no darte de baja: suscríbete enOnEnabley desuscríbete enOnDisable. Si no, provocas fugas y llamadas a objetos destruidos. - Depender del orden entre dos
Update: el orden entre scripts distintos no está garantizado salvo que lo fijes en Script Execution Order. - Confiar en
Startde un objeto desactivado: si el objeto está inactivo, suStartno corre hasta que se active.
Buenas prácticas#
Awake→ referencias propias.Start→ dependencias externas.- Física en
FixedUpdate; input y lógica enUpdate; cámara enLateUpdate. - Empareja siempre
OnEnable/OnDisablepara suscripción/baja de eventos. - Si un script no necesita
Update, no lo dejes vacío: bórralo (Unity paga un pequeño coste por cadaUpdateexistente).
Rendimiento#
Cada MonoBehaviour con un método Update (aunque esté vacío) entra en la lista que Unity recorre cada fotograma, con un pequeño coste de marshalling entre C++ y C#. Con miles de objetos, esto se nota. Alternativas: un único "manager" que actualice a los demás, o desactivar componentes que no hagan nada.
Cuándo NO usar Update#
Si algo no necesita comprobarse cada fotograma, no lo pongas en Update. Ejemplos:
- Comprobaciones periódicas (cada 0,5 s): usa una corrutina con
WaitForSecondsoInvokeRepeating. - Reacciones a sucesos puntuales: usa eventos, no un
ifque se evalúa 60 veces por segundo.
Ponte a prueba#
Checklist#
Resumen#
El ciclo de vida es el contrato entre tu código y el motor: Unity te llama en momentos concretos y en un orden fijo. Inicializa lo tuyo en Awake, lo que dependa de otros en Start, pon la física en FixedUpdate, la lógica en Update y la cámara en LateUpdate. Con eso interiorizado, la mayoría de bugs "misteriosos" de los principiantes desaparecen.