I was trying to implement a double jump in Unity, but I have a problem implementing it. I already have a normal jump, but the problem is with the second one.
I was trying to use
Input.GetButtonUp("Jump")
, but my player has problems with this second jump. In console I see that my player makes this jump but in real his not. Sometimes I need to press space like 30 times to make this second jump, even If I see in Console that he made it many times.
I was trying to implement it by using
jump = Input.GetAxisRaw("Jump");
but in this case, if we press space, we will receive 30 function calls before we jump, and the ground check is set to false.
public class PlayerBHV : MonoBehaviour
{
private float horizontal;
private float jump;
public float speed = 1000f;
public float jumpHeight = 50f;
public float run = 1.5f;
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask WhatIsGround;
public bool grounded;
public bool doubleJump;
[SerializeField] private Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
}
private bool IsGrounded()
{
return grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius ,WhatIsGround);
}
// Update is called once per frame
void Update()
{
IsGrounded();
horizontal = Input.GetAxisRaw("Horizontal");
jump = Input.GetAxisRaw("Jump");
if (grounded && jump == 0)
{
doubleJump = false;
}
if (rb != null)
{
if (Input.GetKey(KeyCode.LeftShift))
{
rb.velocity = new Vector2(horizontal, 0) * Time.fixedDeltaTime * speed * run;
}
if (!Input.GetKey(KeyCode.LeftShift))
{
rb.velocity = new Vector2(horizontal, 0) * Time.fixedDeltaTime * speed;
}
if (jump != 0 && grounded)
{
rb.velocity = new Vector2(horizontal, jumpHeight);
Debug.Log("skok");
}
if (jump != 0 && !doubleJump && !grounded)
{
Debug.Log("tutaj");
rb.velocity = new Vector2(horizontal, jumpHeight);
doubleJump = true;
}
}
}
private void FixedUpdate()
{
rb = GetComponent<Rigidbody2D>();
}
}
CodePudding user response:
Look at what you're doing here. Right after your rigidbody null check, you SET the rb.velocity y component to zero.
if (rb != null)
{
if (Input.GetKey(KeyCode.LeftShift))
{
rb.velocity = new Vector2(horizontal, 0) * Time.fixedDeltaTime * speed * run;
}
if (!Input.GetKey(KeyCode.LeftShift))
{
rb.velocity = new Vector2(horizontal, 0) * Time.fixedDeltaTime * speed;
}
So if you hit left shift, or don't hit left shift, vertical speed gets set to zero. Later you check about jumping, but it doesn't matter - next frame you set vertical speed to zero. I would get current velocity and set only the x component, like
var velocity = rb.velocity;
velocity.x = // your formula for speed
rb.velocity = velocity;
CodePudding user response:
Edit: I overlooked something when answering this question meaning everything I written bellow is incorrect.
private bool IsGrounded() { return grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius ,WhatIsGround); }
This is a pure method, meaning it does not change any data - only returns a value.
In:
void Update()
{
IsGrounded();
You're executing IsGrounded() but ignoring the value it returns, you should be assigning your grounded boolean to the return value of IsGrounded(), like this:
void Update()
{
grounded = IsGrounded();