Efectos Visuales de Daño en Unity: Parpadeo y Color de Texto

Clase 38 de 60Curso Avanzado de Creación de RPGs con Unity

Resumen

Domina un flujo claro en Unity con C#: muestra el daño de enemigos y jugador con números flotantes y añade un parpadeo visual para distinguir cuándo recibes golpes. Esta guía sintetiza la lógica clave, variables y métodos usados para lograr un feedback de daño legible y escalable.

¿Cómo mostrar daño del enemigo y del jugador en Unity?

La clave está en reutilizar el mismo DamageNumber tanto para el ataque del jugador como para el del enemigo. Como el componente no referencia emisor ni receptor, basta con instanciarlo desde el script del enemigo (por ejemplo, en DamagePlayer) y asignarlo desde el editor al prefab del enemigo. Así garantizas consistencia visual.

  • Reutiliza el mismo prefab de DamageNumber para ambos sentidos del daño.
  • Instancia el número en la posición de la colisión del enemigo con el jugador.
  • Asegura rotación neutra para evitar texto girado.
  • Pasa los puntos de daño al componente DamageNumber.
// En DamagePlayer
public GameObject damageNumber; // Asignar desde el editor.

// Dentro del if donde confirmas el daño al jugador:
var clone = (GameObject)Instantiate(
    damageNumber,
    collision.gameObject.transform.position,
    Quaternion.Euler(Vector3.zero)
);

clone.GetComponent<DamageNumber>().damagePoints = damage;

Tip: al modificar el prefab del enemigo, sobrescribe cambios para propagar a instancias hijas.

¿Cómo diferenciar visualmente el daño recibido con parpadeo?

Si los números de daño comparten color, surge confusión. Solución: haz que el personaje parpadee al recibir golpes. Se controlará desde el gestor de vida (por ejemplo, HealthManager) con un flash temporal ajustable. En enemigos, deja la duración a 0 para desactivar el efecto.

  • Usa variables para activar el flash y medir su duración.
  • Accede al sprite renderer para controlar el canal alfa.
  • Alterna visibilidad en tercios del tiempo para un parpadeo claro.
// En HealthManager
public bool flashActive;
public float flashLength;      // duración del parpadeo en segundos.
private float flashCounter;    // contador interno.

private SpriteRenderer characterRenderer; // acceso al sprite del jugador.

void Start() {
    characterRenderer = GetComponent<SpriteRenderer>();
}

Activa el parpadeo cuando el personaje reciba daño, solo si está configurado:

// Dentro de DamageCharacter(...)
if (flashLength > 0f) {
    flashActive = true;
    flashCounter = flashLength;
}

Cambia la visibilidad con una función que ajusta la alfa del color. Así no alteras los canales RGB originales del personaje:

private void ToggleColor(bool visible) {
    var c = characterRenderer.color;
    characterRenderer.color = new Color(c.r, c.g, c.b, visible ? 1f : 0f);
}

Gestiona el parpadeo en update con un esquema por tercios: ocultar, mostrar, ocultar y, al finalizar, volver a mostrar.

void Update() {
    if (flashActive) {
        flashCounter -= Time.deltaTime;

        if (flashCounter > flashLength * 0.66f) {
            ToggleColor(false);
        } else if (flashCounter > flashLength * 0.33f) {
            ToggleColor(true);
        } else if (flashCounter > 0f) {
            ToggleColor(false);
        } else {
            ToggleColor(true);
            flashActive = false;
        }
    }
}

Recomendación: configura flashLength del jugador a, por ejemplo, 1.0. Para enemigos, déjalo en 0 para no parpadear. Otra variante visual posible: cambiar el color del texto de daño para recibido vs infligido.

¿Qué habilidades y conceptos refuerzas con este ejercicio?

Este flujo practica pilares de C# y Unity orientados a gameplay legible y mantenible.

  • Reutilización de componentes y prefabs sin acoplar emisor/receptor del daño.
  • Asignación desde el editor y sobrescritura del prefab padre para propagar cambios.
  • Posicionamiento en colisiones con collision.gameObject.transform.position.
  • Instanciación con Instantiate y orientación neutra con Quaternion.Euler(Vector3.zero).
  • Comunicación entre componentes con GetComponent().damagePoints.
  • Feedback visual controlando SpriteRenderer.color y el canal alfa para visibilidad.
  • Temporización con Time.deltaTime y contador decreciente.
  • Control por tramos porcentuales para animaciones simples y legibles.
  • Uso del operador ternario para asignaciones compactas en C#.
  • Diseño configurable: variables públicas para el inspector y privadas para estado interno.

¿Tienes otra idea para distinguir daño recibido, como variar el color de los números o añadir un pequeño shake? Comparte tu enfoque y dudas en los comentarios.

      Efectos Visuales de Daño en Unity: Parpadeo y Color de Texto