Skip to content
Wonderful Code See
Wonderful Code See

Master the Code, Shape Your Future

  • Home
  • IT Consulting
  • Artificial Intelligence
  • CS Fundamentals
    • Data Structure and Algorithm
    • Computer Network
  • System Design
  • Programming
    • Python Stack
    • .NET Stack
    • Mobile App Development
    • Web Development
    • Unity Tutorials
  • Technology Business
    • Website building tutorials
  • IDE and OA
  • Dev News
Wonderful Code See

Master the Code, Shape Your Future

Unity in Practice 0014 – Unity 2D Dash and Dash Cooldown with Time.deltaTime

WCSee, May 13, 2025May 17, 2025

Implementing a smooth dash system in a 2D Unity game involves several key parts: detecting input, moving the player rapidly for a short time (dash), and then preventing repeated dashing by using a cooldown. This tutorial will walk you through building that system with clean, frame-rate-independent code using Time.deltaTime.

✅ What You’ll Learn

By the end of this tutorial, you’ll understand how to:

  • Make your 2D character dash in the direction they’re facing.
  • Control how long the dash lasts using a timer.
  • Prevent the player from dashing again too soon by adding a cooldown.
  • Write consistent, reliable dash logic that works smoothly across different frame rates by using Time.deltaTime.
  • Handle everything within the Update() method, avoiding the use of coroutines for simplicity and direct control.

🧰 Unity 2D Dash Setup (Quick Steps)

Before we get to the code, make sure your scene is set up properly:

  1. Create a 2D GameObject for your player character.
  2. Add a Rigidbody2D component to it.
  3. Make sure the Rigidbody’s Body Type is set to Dynamic, and Gravity Scale is set to 0 if you don’t want gravity to affect the player.
  4. Attach the following C# script to the player GameObject.
Unity 2D Dash Setup

🧠 Full Unity 2D Dash Script (with Timer and Cooldown)

using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;

public class PlayerScript : MonoBehaviour
{

    private Rigidbody2D rb;
    private Animator playerAnim;

    [SerializeField] private float moveSpeed = 5;
    [SerializeField] private float jumpForce = 10;

    private float xInput;

    private int facingDirection = 1;
    private bool facingRight = true;

    [Header("Collision Info")]
    [SerializeField] private LayerMask groundLayer;
    [SerializeField] private float groundCheckDistance;
    private bool isGrounded;

    [Header("Dash Info")]
    [SerializeField] private float dashSpeed;
    [SerializeField] private float dashDuration;
    private float dashTime;

    [SerializeField] private float dashCooldown;
    private float dashCooldownTime;


    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        playerAnim = GetComponentInChildren<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        CheckInput();

        CollisionChecks();

        Movement();

        // Dash and Cool Down
        dashTime -= Time.deltaTime;
        dashCooldownTime -= Time.deltaTime;


        // Flip the player based on input direction
        FlipController();

        AnimatePlayer();
    }


    private void CollisionChecks()
    {
        isGrounded = Physics2D.Raycast(transform.position, Vector2.down, groundCheckDistance, groundLayer);
    }

    private void CheckInput()
    {
        // Get horizontal input
        xInput = Input.GetAxis("Horizontal");

        // Jump on Space key press
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Jump();
        }

        if (Input.GetKeyDown(KeyCode.LeftShift))
        {
            DashAbility();
        }
    }

    private void DashAbility()
    {
        if (dashCooldownTime < 0)
        {
            dashCooldownTime = dashCooldown;
            dashTime = dashDuration;
        }
    }

    private void Movement()
    {
        if (dashTime > 0)
        {
            rb.velocity = new Vector2(xInput * dashSpeed, 0);
        }
        else
        {
            rb.velocity = new Vector2(xInput * moveSpeed, rb.velocity.y);
        }
    }

    private void Jump()
    {
        if (isGrounded)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
        }
    }

    private void AnimatePlayer()
    {
        // Animate player running
        bool isRun = rb.velocity.x != 0;

        playerAnim.SetFloat("yVelocity", rb.velocity.y);

        playerAnim.SetBool("isRun", isRun);
        playerAnim.SetBool("isGrounded", isGrounded);
        playerAnim.SetBool("isDashing", dashTime > 0);
    }

    private void Flip()
    {
        facingDirection = facingDirection * -1;
        facingRight = !facingRight;

        transform.Rotate(0, 180, 0);
    }

    private void FlipController()
    {
        if (rb.velocity.x > 0 && !facingRight)
        {
            Flip();
        }
        else if (rb.velocity.x < 0 && facingRight)
        {
            Flip();
        }
    }

    private void OnDrawGizmos()
    {
        Gizmos.DrawLine(transform.position, new Vector3(transform.position.x, transform.position.y - groundCheckDistance));

    }
}

📝 How It Works

This script works by splitting the dash behavior into three key responsibilities: handling input, timing the dash duration, and managing cooldown. When the player presses the dash key (in this case, LeftShift) and is allowed to dash, the system sets the velocity to a fast value in the character’s facing direction and starts a dash timer. Once the timer runs out, the character’s velocity is reset, and a separate cooldown timer begins counting down before dashing is enabled again.

The use of Time.deltaTime ensures that both the dash duration and the cooldown countdown are consistent across all machines, regardless of frame rate.

Tips: Systematic Learning Roadmap: Unity Game Development – Systematic Learning Roadmap (2025 Edition)

Please follow and like us:
RSS
Facebook
Facebook
fb-share-icon
X (Twitter)
Visit Us
Follow Me
Tweet
Pinterest
Pinterest
fb-share-icon
Post Views: 105

Related posts:

Unity in Practice 0012 – Blend Tree in Unity Unity in Practice 0011 – Player Jump with Ground Check in Unity Unity in Practice 0010 – Flipping a 2D Character Horizontally in Unity Unity in Practice 0009 – How to Use Sprite Sheets in Unity for 2D Animation and UI Unity in Practice 0008 – Encapsulation and Inspector Access with Unity’s [SerializeField] Unity in Practice 0007 – Very First Unity C# Code to Move and Jump a 2D Ball Unity Game Development – Systematic Learning Roadmap (2025 Edition) Unity in Practice 0005 – Create C# Script
Unity Tutorials Unity DashUnity Game Development

Post navigation

Previous post
Next post

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Set Up and Customize Website Using WordPress | Building Website Tutorials Part 4
  • How to Export Wide Excel sheet to PDF Without Cutting Columns
  • Register a Domain Name and Set Up Hosting | Building Website Tutorials Part 3
  • Choose the Right Website Platform or Builder | Building Website Tutorials Part 2
  • Define Your Website Purpose Clearly | Building Website Tutorials Part 1
  • How to Build a Website from Scratch (Step-by-Step Guide for Beginners)
  • IT Due Diligence and IT Audit: What’s the Differences
  • How to Check SSL/TLS Versions and Cipher Suites on macOS and Windows
  • IT Audit Guide Part 8: IT Audit Best Practices
  • IT Audit Guide Part 7: IT Audit Deliverables

Recent Comments

    Categories

    • CS Fundamentals (1)
      • Computer Network (1)
    • IDE and OA Tool Tips (1)
    • IT Consulting (24)
    • Programming (16)
      • Python Stack (1)
      • Unity Tutorials (15)
    • System Design (1)
    • Technology Business (6)
      • Website building tutorials (5)

    Archives

    • May 2025 (49)
    ©2025 Wonderful Code See | WordPress Theme by SuperbThemes
    Manage Consent
    To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
    Functional Always active
    The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
    Preferences
    The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
    Statistics
    The technical storage or access that is used exclusively for statistical purposes. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
    Marketing
    The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
    Manage options Manage services Manage {vendor_count} vendors Read more about these purposes
    View preferences
    {title} {title} {title}