How do I keep the momentum while jumping

Hey everyone. I’m making a movement script for a 2d platformer and I’m stuck. When I try to jump forward, I have to press and hold the forward motion. I want it so when I release forward while jumping it’ll keep the momentum.

heres the script:

using UnityEngine;
using System.Collections;

public class Movement : MonoBehaviour
{
    public float speed;
    public float jumpPower;
    public Transform jumpEnd;
    public float maxSpeed;


    private Animator _anim;
    private Rigidbody2D _rb2d;
    private bool _isWalking;
    private bool _isFacingRight;
    private bool _isGrounded;
    private bool _jump;

    void Awake ()
    {
        _anim = GetComponent<Animator>();
        _rb2d = GetComponent<Rigidbody2D>();
    }

    void Update()
    {   //check if its grounded
        _isGrounded = Physics2D.Linecast(transform.position,jumpEnd.position, 1 << LayerMask.NameToLayer("Ground"));
        if(Input.GetButtonDown("Jump") && _isGrounded)//check for input and if itsgrounded
            _jump = true;
    }

    void FixedUpdate ()
    {
        //movement
        float h = (Input.GetAxis("Horizontal"));
        _rb2d.velocity = new Vector2 (h * speed, _rb2d.velocity.y);
        //calls animation
         _isWalking = Mathf.Abs(h) > 0;
        _anim.SetBool("IsRunning", _isWalking);
        //make the character face the right direction
        if(h < 0 && !_isFacingRight)
            Flip();
        else if (h > 0 && _isFacingRight)
            Flip();
        //jumping
        if(_jump)
        {
            _rb2d.AddForce(new Vector2(_rb2d.velocity.x,jumpPower));
            _jump = false;
        }
    }

    void Flip()
    {
        _isFacingRight = !_isFacingRight;
        Vector3 scale = transform.localScale;
        scale.x *= -1;
        transform.localScale = scale;
    }
}

line 36 overwrites the current horizontal velocity with a value based on the current horizontal input. If you let go of the key the input is zero and the line overwrites the velocity with 0.

Simplest “fix” would be to include an “isGrounded” check in the fixedupdate such that that line is skipped if the entity isn’t grounded. This would however mean you won’t be able to change horizontal speed whilst not on the floor…

Thanks a lot LeftyRighty that fixed the issue but as you said it prevents me from having any movement in air. What is the best way to fix this issue? Should I try using AddForce instead of the velocity?

Heres my new code and it seems to work fine. Now the problem is I get stuck to the wall because I had to increase the friction so the character won’t slide but thats for another topic. Thanks again.

 void FixedUpdate ()
    {
        if(alive)
        {
            float h = (Input.GetAxisRaw("Horizontal"));
            //movement
            _rb2d.AddForce((Vector2.right * speed) * h);

            //limiting the speed of the player
            if(_rb2d.velocity.x > maxSpeed)
                _rb2d.velocity = new Vector2(maxSpeed, _rb2d.velocity.y);
            if(_rb2d.velocity.x < -maxSpeed)
                _rb2d.velocity = new Vector2(-maxSpeed, _rb2d.velocity.y);
            //calls animation
            _isWalking = Mathf.Abs(h) > 0;
            _anim.SetBool("IsRunning", _isWalking);
            //make the character face the right direction
            if(h < 0 && !_isFacingRight)
                Flip();
            else if (h > 0 && _isFacingRight)
                Flip();
            //jumping
            if(_jump)
            {
                _rb2d.AddForce(new Vector2(_rb2d.velocity.x,jumpPower));
                _jump = false;
            }
            //toxin reduction
            if(Mathf.Abs(h) > 0)
            {
                StatManager.ToxinReduce(runReductionValue * Time.deltaTime);
            }
            StatManager.HealthReduce(healthReductionValue * Time.deltaTime);
        }         
    }

Hello! I know this is more than 4 years late but I just wanted to share my solution for line 36, and thoughts on the jump problem.

For line 36, I used the Horizontal Input as a conditional for what and how much the rigidbody’s horizontal velocity changes. This means that the rigidbody’s velocity decreases to 0 instead of instantly changing after horizontal input is stopped.

if (h < 0)
{
_rb2d.velocity = new Vector2 (speed * -1, _rb2d.velocity.y);
}
else if (h > 0)
{
_rb2d.velocity = new Vector2 (speed, _rb2d.velocity.y);
}

To maintain jump momentum I just used an addforce to the rigidbody and included a groundcheck to avoid aerial movement, which you did.

My solution for the movement could probably be done better, or by using addforce. I imagine you and anyone reading this years later like me probably needs or wants to use manipulate velocity directly.

1 Like

Hi! Again this may be some years late and not the exact answer to the question, but I figured I should post it here. This is a code that decelerates the player, after releasing the move buttons. This also applies to a jump. I know the code isn’t very efficient, but at least it works for me.

public class playerMovement : MonoBehaviour
{

    public float speed;
    public float minSpeed;
    public float maxSpeed;
    private float newSpeed;
    public float acceleration;

    private Rigidbody2D rb;
    private float horizontalMove;

void Start()
{
    rb = GetComponent<Rigidbody2D>();
    newSpeed = minSpeed;
}

 void Update()
    {

        //movement with momentum / acceleration
        horizontalMove = Input.GetAxisRaw("Horizontal");

        if (Input.GetKeyDown(KeyCode.LeftShift))
        {
            newSpeed = maxSpeed;
        }
        if (Input.GetKeyUp(KeyCode.LeftShift))
        {
            newSpeed = minSpeed;
        }

        if (horizontalMove > 0)
        {
            speed = newSpeed;
        }


        if (horizontalMove < 0)
        {
            speed = newSpeed * -1;
        }


        rb.velocity = new Vector2(speed, rb.velocity.y);

        if (horizontalMove == 0 && speed > 0)
        {
            speed -= acceleration;
        }
        if (horizontalMove == 0 && speed < 0)
        {
            speed += acceleration;
        }

        if (speed < 1f && speed > -1f)
        {
            speed = 0f;
        }
}
}

You can also change the acceleration when the player is in the air.

        if (isJumping)
        {
            acceleration = minAcceleration;
        }
        else
        {
            acceleration = maxAcceleration;
        }

Wow I appreciate you coming back with this!
Kudos!! <3