Hey!
I’ve written a script for 2d movement with functionality for running left or right, and jumping.
The running stuff has acceleration and drag but I’ve realised that applying the drag to my rigidbody affects jumping too.
If I jump while running, I jump fairly high. But if I jump while standing still, I hardly leave the ground.
The problem line is “rb.drag = groundDrag;”
I don’t want to move the jump lines from Update() into FixedUpdate() because it can cause some inputs to be eaten. I’ve also seen some similar threads that have suggested creating a custom drag method to slowly decrease velocity.x over time could lead to other issues.
What should I do here? Thanks.
Relevant code:
void Update()
{
runDirection = Input.GetAxisRaw("Horizontal");
if (Input.GetButtonDown("Jump") && IsGrounded())
{
rb.velocity = new Vector2 (rb.velocity.x, jumpForce);
}
}
private void FixedUpdate()
{
GroundMove();
ApplyGroundDrag();
}
private void GroundMove()
{
rb.AddForce(new Vector2(runDirection * accelSpeed, 0f), ForceMode2D.Impulse);
if (Mathf.Abs(rb.velocity.x) > maxSpeed)
{
rb.velocity = new Vector2(Mathf.Sign(rb.velocity.x) * maxSpeed, rb.velocity.y);
}
}
private void ApplyGroundDrag()
{
if (Mathf.Abs(runDirection) == 0)
{
rb.drag = groundDrag;
}
else
{
rb.drag = 0f;
}
}
You could try setting the drag to 0 when you are not grounded. That might break if you add wall sliding or something like that, but seems like a good first thing to try.
1 Like
Ah! That’s partially fixed the issue. I changed the drag section to:
if (Mathf.Abs(runDirection) == 0 && IsGrounded())
and that seems to have increased the height of my stationary jump. It’s still slightly shorter than if I were to run+jump due to the short period of time where I’m initiating the jump but the BoxCast that checks for grounding is still touching the floor, but this is definitely an improvement. Thanks 
Another method I’ve had success with is to remove drag altogether and use different physics materials based on the movement impulse input. One with zero friction while the input is signalling to move and one with normal friction otherwise. It can have a few adverse effects when dealing with slopes but that’s a whole 'nother ballgrame in general anyway.
1 Like
After toying around with it a bit more, I’ve found something that seems to work in all test cases I’ve tried.
I created private bool isJumping = false;
and changed the Update and FixedUpdate methods like so:
void Update()
{
runDirection = Input.GetAxisRaw("Horizontal");
if (IsGrounded() && isJumping)
{
isJumping = false;
}
if (Input.GetButtonDown("Jump") && IsGrounded())
{
isJumping = true;
rb.drag = 0;
rb.velocity = new Vector2 (rb.velocity.x, jumpForce);
}
}
private void FixedUpdate()
{
GroundMove();
if(!isJumping)
{
ApplyGroundDrag();
}
Now, whenever the user wants (and is able) to jump, isJumping will be set to true and the GroundDrag method won’t be called. As soon as the player is grounded again after jumping, isJumping will be set back to false and drag will apply once again.
This seems to work fine in testing. I figured I’d post it here for future reference and for anyone to point out any glaring errors or oversights.