El objetivo#
Un impulso rápido en la dirección en la que se mueve el personaje, que dura un instante, tiene un tiempo de reutilización (cooldown) y no se ve afectado por la gravedad mientras dura.
Requisitos#
Un personaje 2D con Rigidbody2D y Collider2D (base de la receta de movimiento 2D). Usaremos una corrutina para controlar la duración.
La receta#
using System.Collections;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
public class Dash : MonoBehaviour
{
[SerializeField] private float fuerzaDash = 24f;
[SerializeField] private float duracion = 0.15f;
[SerializeField] private float cooldown = 1f;
private Rigidbody2D rb;
private bool puedeHacerDash = true;
private bool haciendoDash = false;
private float ultimaDireccionX = 1f; // hacia dónde mira
void Awake() => rb = GetComponent<Rigidbody2D>();
void Update()
{
float x = Input.GetAxisRaw("Horizontal");
if (x != 0) ultimaDireccionX = Mathf.Sign(x);
if (Input.GetKeyDown(KeyCode.LeftShift) && puedeHacerDash)
StartCoroutine(HacerDash());
}
IEnumerator HacerDash()
{
puedeHacerDash = false;
haciendoDash = true;
float gravedadOriginal = rb.gravityScale;
rb.gravityScale = 0f; // sin gravedad durante el dash
rb.linearVelocity = new Vector2(ultimaDireccionX * fuerzaDash, 0f);
yield return new WaitForSeconds(duracion); // dura un instante
rb.gravityScale = gravedadOriginal; // restaurar
haciendoDash = false;
yield return new WaitForSeconds(cooldown); // espera antes de poder repetir
puedeHacerDash = true;
}
// Otros scripts pueden consultar esto para no pelearse con el movimiento
public bool HaciendoDash => haciendoDash;
}Por qué así#
- Guardamos la última dirección para que el dash vaya hacia donde miras aunque sueltes la tecla.
- Gravedad a 0 durante el dash: da un impulso recto y limpio; la restauramos al terminar.
- Dos esperas en la corrutina: la primera controla la duración del dash; la segunda, el cooldown antes de poder repetir.
Si tienes un script de movimiento que fija linearVelocity en FixedUpdate, sobrescribirá el dash. Consúltale HaciendoDash y, mientras sea true, que no toque la velocidad:
void FixedUpdate()
{
if (dash.HaciendoDash) return; // deja actuar al dash
rb.linearVelocity = new Vector2(entradaX * velocidad, rb.linearVelocity.y);
}Mejoras habituales#
- Feedback: un rastro (Trail Renderer), un sonido y un pequeño screen shake hacen que el dash "sienta" bien.
- Dash en 8 direcciones: usa el vector completo de input (
new Vector2(x, y).normalized) en vez de solo la X. - Invulnerabilidad: muchos juegos hacen al jugador inmune durante el dash (cambiando su layer un instante).
Errores frecuentes#
- Que el script de movimiento sobrescriba la velocidad del dash (comprueba
HaciendoDash). - Olvidar restaurar
gravityScaley que el personaje flote para siempre. - No poner cooldown y permitir dash infinito.
- Leer el input del dash en
FixedUpdate(usaUpdate).
Resumen#
Un dash es un impulso corto: guarda la dirección, en una corrutina pon la gravedad a 0, fija linearVelocity con la fuerza del dash, espera la duración, restaura, y espera el cooldown. Expón HaciendoDash para que el movimiento normal no lo pise. Añádele rastro, sonido e invulnerabilidad para que sienta de lujo.