Crear un sistema de vida robusto en Unity no tiene por qué ser complejo. Con un único health manager genérico en C#, podrás controlar la vida máxima, la vida actual, el daño y la inactivación del objeto cuando llega a cero. Este enfoque es reusable para jugador, enemigos o NPCs, y simplifica el diseño del combate.
¿Qué resuelve un health manager genérico en Unity?
Un solo script administra la vida de cualquier entidad: jugador, enemigo o NPC. No referencia al personaje de forma directa, lo que favorece la abstracción y la reutilización del código. La lógica es uniforme: si la vida actual llega a cero, el GameObject se desactiva.
- Un mismo script para todos. Menos duplicación y menos errores.
- Control centralizado de vida. Más fácil de ajustar y depurar.
- Comportamiento consistente. Mismas reglas para jugador y enemigos.
¿Qué variables controlan la vida?
Se usan dos enteros públicos para observación rápida en el Inspector de Unity: maxHealth y currentHealth. Al iniciar con Start, la vida actual se iguala a la máxima. En Update, si currentHealth ≤ 0, se llama a gameObject.SetActive(false).
using UnityEngine;
public class HealthManager : MonoBehaviour
{
public int maxHealth;
public int currentHealth;
void Start()
{
currentHealth = maxHealth; // Al iniciar, vida al máximo.
}
void Update()
{
if (currentHealth <= 0)
{
gameObject.SetActive(false); // Inactivar al llegar a 0.
}
}
}
- Si prefieres encapsular, puedes mantenerlas privadas y mostrarlas con [SerializeField].
- Ventaja práctica: observar valores en el Inspector acelera pruebas.
¿Qué métodos gestionan daño y nivel?
Se implementan dos métodos clave: uno para aplicar daño y otro para actualizar vida máxima tras un level up (rellenando la vida al máximo, estilo Diablo 3).
public void DamageCharacter(int damage)
{
currentHealth -= damage; // Restar daño recibido.
}
public void UpdateMaxHealth(int newMaxHealth)
{
maxHealth = newMaxHealth; // Nueva vida máxima.
currentHealth = maxHealth; // Rellenar vida al subir de nivel.
}
- Daño parametrizable. No se usan números "a piñón" dentro del código.
- Subida de nivel coherente. Rellenar vida es común en juegos de rol.
¿Cómo se implementa el daño del enemigo sin lógica drástica?
El daño deja de “matar” de golpe con setActive(false) en el script del enemigo. En su lugar, el enemigo detecta el HealthManager del objeto con el que colisiona (por ejemplo, el jugador) y llama a DamageCharacter(damage). Solo se mantiene una variable pública damage para configurar el daño.
¿Cómo adaptar el damage player para colisiones?
En el manejador de colisión, se recupera el componente y se aplica daño configurado desde el Inspector.
public int damage; // Daño que inflige el enemigo.
// Dentro del manejador de colisión correspondiente
var hm = collision.gameObject.GetComponent<HealthManager>();
if (hm != null)
{
hm.DamageCharacter(damage);
}
- Se elimina lógica de reactivación, contadores y tiempos de vida no necesarios.
- Código más limpio. Cada componente hace una tarea concreta.
¿Qué queda obsoleto en el script anterior?
- Variables de reaparición y tiempos de revivir. Eliminadas.
- setActive(false) directo al colisionar. Sustituido por el HealthManager.
- Start vacío o innecesario. Puede omitirse si no se usa.
¿Cómo probar el sistema en el editor de Unity?
Asignar componentes y valores permite ver el sistema en acción desde el Inspector sin interfaz gráfica de vida.
¿Qué cambios hacer en el inspector y en el prefab?
- Asigna el HealthManager al jugador con una vida máxima de 200 puntos.
- En el prefab del enemigo, establece damage = 10.
¿Cómo verificar el comportamiento en tiempo real?
¿Qué habilidades, conceptos y keywords aparecen y por qué importan?
- Componentización en Unity. Reutilizar un script para jugador, enemigo y NPC.
- Encapsulación de estado: maxHealth y currentHealth controlados desde el Inspector.
- Ciclo de vida de Unity: Start para inicializar, Update para verificar condiciones.
- Gestión de colisiones: uso de collision.gameObject.GetComponent().
- Parámetros y métodos: DamageCharacter(int), UpdateMaxHealth(int).
- Buenas prácticas: evitar "números mágicos" y exponer damage como variable pública.
- Flujo de juego: inactivar GameObject en 0 y planificar game over.
¿Te gustaría ver cómo conectar este sistema con barras de vida en UI o con un set de armas? Comparte tus dudas y cuéntame qué implementarías a continuación.