Help Needed with Dash Mechanism in 2D Player Movement Script

Hello everyone,

I’m currently working on a 2D player movement script in Unity, and I’m facing an issue with the dash mechanism. I have implemented the dash in the PlayerMovement script, where the player moves towards the mouse position when the spacebar is pressed. However, although the input is being recognized correctly, the player doesn’t actually dash as expected.

Here’s the relevant portion of my code:


using System;
using System.Collections;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    [Header("Important References")]
    [HideInInspector] public Rigidbody2D playerRb; 
    public GameObject PlayerPosition; 
    [SerializeField] private float PlayerPositionRadius = 0.2f; 
    public LayerMask GroundMask; 
    [HideInInspector] public float moveDirectionX; 
    [HideInInspector] public float moveDirectionY;

    [Header("Player-Movement-Settings")]
    [SerializeField] private float playerRunningSpeed = 5f; 
    [HideInInspector] public static bool allowRunning = true; 

    [Header("Player-Gravity-Settings")]
    [HideInInspector] public bool Grounded; 
    [SerializeField] private float TimeToUseMoreGravity;
    [SerializeField] private float IncreaseGravity; 
    private Coroutine GravityCoroutine; 
    public float GravityOnAir = 20f; 
    public float GravityOnGround = 1f; 
    [Space(10)]

    [Header("Player-DashSystem")]
    [SerializeField] private float DashPower = 5f; 
    //[SerializeField] private float DashCooldown; 
    private Vector2 direction;
    void Start()
    {
        playerRb = GetComponent<Rigidbody2D>(); 
    }

    void Update()
    {
        GetInputs(); // Nur einmal aufrufen
        GroundCheck();
        UseGravity();
        GetMouseDates();
        UseDash();

        //Clampen von Gravity
        GravityOnAir = Mathf.Clamp(GravityOnAir, 0, 40f); 

    }

     

    void FixedUpdate()
    {
        if (allowRunning == true)
        {
            RunSystem(); // Call RunSystem in FixedUpdate for consistent physics
        }
    }

    #region AllMethodsOFPlayer


    private void RunSystem()
    {
        // Apply movement based on inputs and speed      
        playerRb.velocity = new Vector2(moveDirectionX * playerRunningSpeed, 0f);         
    }

    private void GetInputs()
    {
        // Getting Inputs
        moveDirectionX = Input.GetAxis("Horizontal"); 
        moveDirectionY = Input.GetAxis("Vertical"); 
    }

    private void GroundCheck()
    {
        RaycastHit2D hitGround = Physics2D.Raycast(PlayerPosition.transform.position, Vector2.down, PlayerPositionRadius, GroundMask);
        {
            if(hitGround.collider != null)
            {
                Grounded = true; //Wenn der Spieler auf dem Boden ist!!
                GravityOnAir = 20f; 
            }
            else 
            {
                Grounded = false; 
                Debug.Log("Der Spieler ist in der Luft");
            }
        }
    }
    private void UseGravity()
    {
        if(Grounded == false) // Der Spieler ist in der Luft, nicht auf den Boden
        {
            playerRb.gravityScale = GravityOnAir; 

            if(GravityCoroutine == null)
            {
                GravityCoroutine = StartCoroutine(GravityMultiplier());
            }
        }

    }
    private void GetMouseDates()
    {
         // Mausposition auf dem Bildschirm abrufen und in Weltkoordinaten umwandeln
        Vector3 mouseWorldPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        
        // Richtung berechnen: Mausposition - Spielerposition
        direction = (mouseWorldPosition - PlayerPosition.transform.position).normalized;
    }

    private void UseDash()
    {
        //DashPower Wird dem Spieler hinzugefügt wenn erlaubt
        if(/*PlayerAnimationsManager.allowDashing == true && */Input.GetKeyDown(KeyCode.Space))
        {
            playerRb.velocity = direction * DashPower; 
            Debug.Log("Der Spieler Dasht!!");
        }
        
    }

    #endregion

    #region  OnDrawGizmos

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.cyan;
        Gizmos.DrawWireSphere(PlayerPosition.transform.position, PlayerPositionRadius);
    }

    #endregion

    #region Courutines 

    private IEnumerator GravityMultiplier()
    {
        yield return new WaitForSeconds(TimeToUseMoreGravity); //Warte, eine gewisse zeit!
        GravityOnAir += IncreaseGravity * Time.fixedDeltaTime;  //Gravitation erhört, (Sie wurde Geclamped)
        Debug.Log("Gravitation wird benutzt");    
        GravityCoroutine = null; // Coroutine-Referenz zurücksetzen 
    }

    #endregion


}

Things I’ve already checked:

  1. The player’s direction towards the mouse position is correctly calculated using GetMouseDates().
  2. The Rigidbody2D component is set to dynamic, ensuring that the velocity change should apply.
  3. Debugging shows that the if(Input.GetKeyDown(KeyCode.Space)) condition is triggered properly.

Despite this, the player doesn’t dash. The velocity isn’t being applied as expected. I suspect it could be related to something with the Rigidbody2D or the velocity calculation itself.

Has anyone experienced something similar or can suggest what I might be missing? Any help would be appreciated!

Thanks in advance!

Dash mechanisms generally involve inhibiting or suspending the player’s inputs for the duration of the dash.

This CAN be made with a coroutine but it is far simpler to just use a simple float timer that you set and count down during the dash.

This latter approach lets you “blend out” the dash speed smoothly towards the end , gradually returning control to the player inputs at the end of the dash.

Generally coroutines are a poor, complicated, and awkward solution to player movements.

Then you haven’t found the bug… that means you need to keep debugging!

By debugging you can find out exactly what your program is doing so you can fix it.

Use the above techniques to get the information you need in order to reason about what the problem is.

You can also use Debug.Log(...); statements to find out if any of your code is even running. Don’t assume it is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

Remember with Unity the code is only a tiny fraction of the problem space. Everything asset- and scene- wise must also be set up correctly to match the associated code and its assumptions.

1 Like

Hello,

Thank you so much for your detailed response! Your explanation really helped me understand the mechanics behind dashing and how player input should be managed during specific actions. After reviewing my code, I realized the issue was indeed related to how I was handling movement updates, and I’ve successfully implemented a fix.

Your advice about suspending player input during the dash and debugging properly has significantly expanded my knowledge, not just about dashing, but about managing complex player behaviors overall. I truly appreciate the time you took to explain this.

Thanks again, and I hope you have a great day!

Best regards,

1 Like