Forum begins after the advertisement:
[Part 2.5] I cant dash. i know that the dash exists but i cant trigger it.
Home › Forums › Video Game Tutorial Series › Creating a Metroidvania in Unity › [Part 2.5] I cant dash. i know that the dash exists but i cant trigger it.
- This topic has 2 replies, 3 voices, and was last updated 2 days ago by
Terence.
-
AuthorPosts
-
January 25, 2026 at 6:20 am #19221::
using System.Collections; using UnityEngine; public class PlayerController : MonoBehaviour { // Start is called once before the first execution of Update after the MonoBehaviour is created [Header("Horizontal Movement Settings")] private Rigidbody2D rb; [SerializeField] private float walkspeed = 1; private float xAxis; [Header("Ground Check Settings")] [SerializeField] private float jumpForce = 45; private float jumpBufferCounter = 0; [SerializeField] private float jumpBufferFrames; private float coyoteTimeCounter = 0; [SerializeField] private float coyoteTime; [Header("Ground")] [SerializeField] private Transform groundCheckPoint; [SerializeField] private float groundCheckY = 0.2f; [SerializeField] private float groundCheckX = 0.5f; [SerializeField] private LayerMask whatIsGround; [SerializeField] private float dashSpeed; [SerializeField] private float dashTime; [SerializeField] private float dashCooldown; PlayerStateList pstate; private float gravity; Animator anim; private bool canDash; private bool dashed; public static PlayerController Instance; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); } else { Instance = this; } } void Start() { pstate = GetComponent<PlayerStateList>(); rb = GetComponent<Rigidbody2D>(); anim = GetComponent<Animator>(); gravity = rb.gravityScale; } // Update is called once per frame void Update() { GetInputs(); UpdateJumpVariables(); if (pstate.dashing) return; Flip(); Move(); Jump(); StartDash(); } void GetInputs() { xAxis = Input.GetAxisRaw("Horizontal"); Debug.Log(xAxis); } void Flip() { if (xAxis < 0) { transform.localScale = new Vector2(-1, transform.localScale.y); } else if (xAxis > 0) { transform.localScale = new Vector2(1, transform.localScale.y); } } private void Move() { rb.linearVelocity = new Vector2(walkspeed * xAxis, rb.linearVelocity.y); anim.SetBool("Walking", rb.linearVelocity.x != 0 && Grounded()); } void StartDash() { if (Input.GetButtonDown("Dash") && canDash && !dashed) { StartCoroutine(Dash()); dashed = true; } if (Grounded()) { dashed = false; } } IEnumerator Dash() { canDash = false; pstate.dashing = true; anim.SetTrigger("Dashing"); rb.gravityScale = 0; rb.linearVelocity = new Vector2(transform.localScale.x * dashSpeed, 0); yield return new WaitForSeconds(dashTime); rb.gravityScale = gravity; pstate.dashing = false; yield return new WaitForSeconds(dashCooldown); canDash = true; } public bool Grounded() { if (Physics2D.Raycast(groundCheckPoint.position, Vector2.down, groundCheckY, whatIsGround) || Physics2D.Raycast(groundCheckPoint.position + new Vector3(groundCheckX, 0, 0), Vector2.down, groundCheckY, whatIsGround) || Physics2D.Raycast(groundCheckPoint.position + new Vector3(-groundCheckX, 0, 0), Vector2.down, groundCheckY, whatIsGround)) { return true; } else { return false; } } void Jump() { { // 1. CUTTING THE JUMP if (Input.GetButtonUp("Jump") && rb.linearVelocity.y > 0) { rb.linearVelocity = new Vector2(rb.linearVelocity.x, 0); pstate.jumping = false; } // 2. TRIGGERING THE JUMP if (!pstate.jumping) { if (jumpBufferCounter > 0 && coyoteTimeCounter > 0) { rb.linearVelocity = new Vector2(rb.linearVelocity.x, jumpForce); pstate.jumping = true; // CRITICAL: Reset these counters so the jump doesn't loop jumpBufferCounter = 0; coyoteTimeCounter = 0; } } anim.SetBool("Jumping", !Grounded()); } } void UpdateJumpVariables() { if (Grounded()) { pstate.jumping = false; coyoteTimeCounter = coyoteTime; } else { coyoteTimeCounter -= Time.deltaTime; } if (Input.GetButtonDown("Jump")) { jumpBufferCounter = jumpBufferFrames; } else { jumpBufferCounter = jumpBufferCounter - Time.deltaTime * 10; } } }January 25, 2026 at 2:18 pm #19223::@ser.apustaja can you have a look at this player controller script and tell me what is wrong with it? The topic creator says he is unable to dash.
using System.Collections; using UnityEngine; public class PlayerController : MonoBehaviour { // Start is called once before the first execution of Update after the MonoBehaviour is created [Header("Horizontal Movement Settings")] private Rigidbody2D rb; [SerializeField] private float walkspeed = 1; private float xAxis; [Header("Ground Check Settings")] [SerializeField] private float jumpForce = 45; private float jumpBufferCounter = 0; [SerializeField] private float jumpBufferFrames; private float coyoteTimeCounter = 0; [SerializeField] private float coyoteTime; [Header("Ground")] [SerializeField] private Transform groundCheckPoint; [SerializeField] private float groundCheckY = 0.2f; [SerializeField] private float groundCheckX = 0.5f; [SerializeField] private LayerMask whatIsGround; [SerializeField] private float dashSpeed; [SerializeField] private float dashTime; [SerializeField] private float dashCooldown; PlayerStateList pstate; private float gravity; Animator anim; private bool canDash; private bool dashed; public static PlayerController Instance; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); } else { Instance = this; } } void Start() { pstate = GetComponent<PlayerStateList>(); rb = GetComponent<Rigidbody2D>(); anim = GetComponent<Animator>(); gravity = rb.gravityScale; } // Update is called once per frame void Update() { GetInputs(); UpdateJumpVariables(); if (pstate.dashing) return; Flip(); Move(); Jump(); StartDash(); } void GetInputs() { xAxis = Input.GetAxisRaw("Horizontal"); Debug.Log(xAxis); } void Flip() { if (xAxis < 0) { transform.localScale = new Vector2(-1, transform.localScale.y); } else if (xAxis > 0) { transform.localScale = new Vector2(1, transform.localScale.y); } } private void Move() { rb.linearVelocity = new Vector2(walkspeed * xAxis, rb.linearVelocity.y); anim.SetBool("Walking", rb.linearVelocity.x != 0 && Grounded()); } void StartDash() { if (Input.GetButtonDown("Dash") && canDash && !dashed) { StartCoroutine(Dash()); dashed = true; } if (Grounded()) { dashed = false; } } IEnumerator Dash() { canDash = false; pstate.dashing = true; anim.SetTrigger("Dashing"); rb.gravityScale = 0; rb.linearVelocity = new Vector2(transform.localScale.x * dashSpeed, 0); yield return new WaitForSeconds(dashTime); rb.gravityScale = gravity; pstate.dashing = false; yield return new WaitForSeconds(dashCooldown); canDash = true; } public bool Grounded() { if (Physics2D.Raycast(groundCheckPoint.position, Vector2.down, groundCheckY, whatIsGround) || Physics2D.Raycast(groundCheckPoint.position + new Vector3(groundCheckX, 0, 0), Vector2.down, groundCheckY, whatIsGround) || Physics2D.Raycast(groundCheckPoint.position + new Vector3(-groundCheckX, 0, 0), Vector2.down, groundCheckY, whatIsGround)) { return true; } else { return false; } } void Jump() { { // 1. CUTTING THE JUMP if (Input.GetButtonUp("Jump") && rb.linearVelocity.y > 0) { rb.linearVelocity = new Vector2(rb.linearVelocity.x, 0); pstate.jumping = false; } // 2. TRIGGERING THE JUMP if (!pstate.jumping) { if (jumpBufferCounter > 0 && coyoteTimeCounter > 0) { rb.linearVelocity = new Vector2(rb.linearVelocity.x, jumpForce); pstate.jumping = true; // CRITICAL: Reset these counters so the jump doesn't loop jumpBufferCounter = 0; coyoteTimeCounter = 0; } } anim.SetBool("Jumping", !Grounded()); } } void UpdateJumpVariables() { if (Grounded()) { pstate.jumping = false; coyoteTimeCounter = coyoteTime; } else { coyoteTimeCounter -= Time.deltaTime; } if (Input.GetButtonDown("Jump")) { jumpBufferCounter = jumpBufferFrames; } else { jumpBufferCounter = jumpBufferCounter - Time.deltaTime * 10; } } }January 25, 2026 at 2:20 pm #19224::The issue with the player being unable to dash may stem from the
canDashvariable not being initialized totrue. In yourStart()method, you should setcanDashtotrueto allow the player to dash initially.Here’s the corrected part of the
Start()method:void Start() { pstate = GetComponent(); rb = GetComponent(); anim = GetComponent(); gravity = rb.gravityScale; canDash = true; // Initialize canDash to true }Additionally, ensure that the “Dash” input is correctly set up in the Unity Input Manager. If the input is not recognized, the dash will not trigger.
If the problem persists, please check if the
dashCooldownis set to a reasonable value and whether thePlayerStateListis functioning correctly.Is there any specific error message or behavior you observe when trying to dash?
January 25, 2026 at 2:22 pm #19225::@hobbebergstrom in the meantime, can you add the following lines to your
StartDash()andDash()function and let me know what the Console shows?void StartDash() { print("StartDash() fired"); if (Input.GetButtonDown("Dash") && canDash && !dashed) { print("Dash() coroutine fired"); StartCoroutine(Dash()); dashed = true; } if (Grounded()) { dashed = false; } } IEnumerator Dash() { canDash = false; pstate.dashing = true; anim.SetTrigger("Dashing"); rb.gravityScale = 0; rb.linearVelocity = new Vector2(transform.localScale.x * dashSpeed, 0); print("Dash() coroutine running"); yield return new WaitForSeconds(dashTime); rb.gravityScale = gravity; pstate.dashing = false; print("Dash() ended"); yield return new WaitForSeconds(dashCooldown); canDash = true; print("Dash() coroutine ended"); } -
AuthorPosts
- You must be logged in to reply to this topic.