Skelerena88
Skelerena88

Reputation: 11

Dash is not adding velocity to player in Unity2d using the new Input System

I am working on a 2d platformer (using Unity and the new Input System) and trying to implement a Dash (similar to Hollow Knight/ Celeste). The Dash is supposed to propel the player horizontally forward (depending on where the player is facing), and can only be activated while Jumping.

However, Dash does not seem to work upon playtesting the game.

When I try to Jump and Dash, the player only moves forward horizontally at the same velocity as the run speed. Everything else within the Coroutine seems to be working fine (including the TrailRenderer).

It feels as though there is no added velocity when dashing.

This is my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerMovement : MonoBehaviour
{

    //drag and drop the component to the script in the inspector
    public Rigidbody2D rb;

    public Transform groundCheck;
    public LayerMask groundLayer;
    public Animator myAnimator;
    public ParticleSystem dust;
    
    //this will make the public float accessible in the inspector
    private float horizontal;
    public float speed = 8f;
    public float jumpingPower = 16f;
    private bool isFacingRight = true;
    
    //coyote time
    public float coyoteTime = 0.1f;
    private float coyoteTimeCounter;
    
    //Dash goes here
    bool canDash = true;
    bool isDashing;
    [SerializeField] float dashForce = 30f;
    [SerializeField] float dashTime = 0.2f; 
    [SerializeField] float dashCooldown = 1f;
    [SerializeField] TrailRenderer dashTrail;
    //Dash Ends here
    
    void Start()
    {
        canDash = true;
    
    }
    
    
    void Update()
    {
        if (IsGrounded())
        {
            coyoteTimeCounter = coyoteTime;
        }
        else
        {
            coyoteTimeCounter -= Time.deltaTime;
        }
    
        if (!isFacingRight && horizontal > 0f)
        {
            Flip();
        }
        else if (isFacingRight && horizontal < 0f)
        {
            Flip();
        }
    
        if (isDashing)
        {
            return;
        }
    
        //Falling();
    
    }
    
    private void FixedUpdate()
    {
        rb.velocity = new Vector2(horizontal * speed, rb.velocity.y);
    
        if (isDashing)
        {
            return;
        }
    }
    
    
    public void Move(InputAction.CallbackContext context)
    {
        horizontal = context.ReadValue<Vector2>().x;
    
        if (Mathf.Abs(horizontal) > 0f)
        {
            myAnimator.SetBool("isRunning", true);
        }
        else
        {
            myAnimator.SetBool("isRunning", false);
        }
    }
    
    
    public void Jump(InputAction.CallbackContext context)
    {
        
        if (context.performed && coyoteTimeCounter > 0f)
        {
            CreateDust();
            rb.velocity = new Vector2(rb.velocity.x, jumpingPower);
        }
    
        if (context.canceled && rb.velocity.y > 0f)
        {
            rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
    
            coyoteTimeCounter = 0f;
        }
    }
    
    
    private bool IsGrounded()
    {
        return Physics2D.OverlapCircle(groundCheck.position, 0.5f, groundLayer);
    }
    
    private void Flip()
    {
        CreateDust();
        isFacingRight = !isFacingRight;
        Vector3 localScale = transform.localScale;
        localScale.x *= -1f;
        transform.localScale = localScale;
    }
    
    
    public void Dash(InputAction.CallbackContext context)
    {
        if (context.performed && canDash && !IsGrounded())
        {
            StartCoroutine(Dash());
        }
    }
    
    private IEnumerator Dash()
    {
        canDash = false;
        isDashing = true;
        float originalGravity = rb.gravityScale;
        rb.gravityScale = 0f;
        rb.velocity = new Vector2(transform.localScale.x * dashForce, 0f); //issue? feels like the player isnt speeding up   
        dashTrail.emitting = true;
        yield return new WaitForSeconds(dashTime);
        dashTrail.emitting = false;
        rb.gravityScale = originalGravity;
        isDashing = false;
        yield return new WaitForSeconds (dashCooldown);
        canDash = true;
    }
    
    void CreateDust()
    {
        dust.Play();
    }

}

I am guessing the error is due to this line here within the coroutine, but I am not sure what to replace it with:

rb.velocity = new Vector2(transform.localScale.x * dashForce, 0f);

Hope this makes sense. This is the first time I am working on a Unity project and I am following tutorials both on Udemy and Youtube - but I could not seem to find an answer for this. Any help is appreciated!

Upvotes: 1

Views: 152

Answers (1)

Xander
Xander

Reputation: 447

Yes, you're just replacing existing velocity vector with completely new one, thus not accounting anything that is set earlier.

This case is indicates, why Unity clearly says:

In most cases you should not modify the velocity directly, as this can result in unrealistic behaviour - use AddForce instead.

By calculating velocities instead of forces and directions one could easily fall into trap of making small mistake in calculations that will ruin everything, besides also loosing the benefits of having the physics engine on its side to handle motion in proper way. Any interruptions of such intricate machine would lead to unnaturally feeling behaviors on first place and many unwanted effects on second and third.

So, to conclude: if you're working with vectors, usually its enough to construct them once (from input) and then only transform - normalize, multiply, invert, rotate (quaternion * vector3) if needed, cut unused axis for 2D and be happy by having zero glitches on that side.

Hope I helped you somehow. Stay awesome :)

Upvotes: 0

Related Questions