Reputation: 67
So I was trying to implement double jumping in my game, which doesn't work. And now, somehow, not only can't my players double jump, they can't even jump either!
update: they can jump now, still can't double jump though.
This is my whole movement script:
using UnityEngine;
namespace Players
{
public class Actor : MonoBehaviour
{
//in order to control both players using 1 script.
public int playerIdx;
//Variables.
public float movementSpeed = 150f;
public float jumpForce = 250f;
//Ground stuff.
public LayerMask whatIsGround;
public bool grounded;
//boolean stuff.
private bool facingRight;
private bool moving;
//Needed to check if player is on the ground.
public Transform groundCheck;
//Limit player's movement speed.
public float maxMovementSpeed = 400f;
//Double jump stuff.
private bool doubleJumpReady;
//rb
private Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
doubleJumpReady = true;
rb = GetComponent<Rigidbody2D>();
facingRight = true;
}
// Update is called once per frame
void FixedUpdate()
{
SlowDown();
}
private void LateUpdate()
{
grounded = Physics2D.OverlapCircle(groundCheck.position, 0.1f, whatIsGround);
if (grounded)
doubleJumpReady = true;
}
private void SlowDown()
{
if (moving) return;
//if player is not moving, slow them down.
if (rb.velocity.x > 0.2f)
rb.AddForce(movementSpeed * Time.deltaTime * -Vector2.right);
if (rb.velocity.x < -0.2f)
rb.AddForce(movementSpeed * Time.deltaTime * Vector2.right);
}
public void Move(int dir)
{
//Flip the player.
Flip(dir);
//Moving the player.
moving = true;
float xVel = rb.velocity.x; //Get x velocity.
if ( dir > 0)
rb.AddForce(movementSpeed * Time.deltaTime * Vector2.right * dir);
else if (dir < 0)
rb.AddForce(movementSpeed * Time.deltaTime * Vector2.right * dir);
else if (dir == 0) { } //do nothing.
//Help player turn around faster.
if (xVel > 0.2f && dir < 0)
rb.AddForce(movementSpeed * 3.2f * Time.deltaTime * -Vector2.right);
if (xVel < 0.2f && dir > 0)
rb.AddForce(movementSpeed * 3.2f * Time.deltaTime * Vector2.right);
}
private void Flip(int dir)
{
if (facingRight && dir == -1 || !facingRight && dir == 1)
{
facingRight = !facingRight;
transform.Rotate(0f, 180f, 0f);
}
}
protected void Jump()
{
if (grounded)
{
rb.AddForce(Vector2.up * jumpForce);
grounded = false;
doubleJumpReady = true;
}
else if (!grounded && doubleJumpReady)
{
rb.AddForce(Vector2.up * jumpForce);
doubleJumpReady = false;
}
}
}
}
I don't know if it is because of my jump script, or my player script:
void Update()
{
if (playerIdx == 1)
{
if (Input.GetKey(KeyCode.A))
Move(-1);
if (Input.GetKey(KeyCode.D))
Move(1);
if (Input.GetKey(KeyCode.W))
Jump();
}
if (playerIdx == 2)
{
if (Input.GetKey(KeyCode.LeftArrow))
Move(-1);
if (Input.GetKey(KeyCode.RightArrow))
Move(1);
if (Input.GetKey(KeyCode.UpArrow))
Jump();
}
}
So how can I fix this?
Upvotes: 0
Views: 3693
Reputation: 467
Going off the assumption that you can now perform the normal jump again after reading the comments. I think the reason you can't 'double jump' is that when you call the Jump()
method, you don't just call it once, you call it twice, so what happens is the player jumps and then immediately double jumps and so you don't actually notice that the double jump has occurred. You could make it so that your doubleJumpReady
boolean is only true after a set amount of time after you have jumped initially using some sort of co-routine or something I implemented for a sort of double jump mechanic once was that the user could press the jump button again to double jump only when the player had reached the maximum height of the initial jump or after.
Upvotes: 1
Reputation: 81
as far as i can see you never reset the
doubleJumpReady = false;
Variable. To fix this simply change the jump code to:
protected void Jump()
{
if (grounded)
{
rb.AddForce(Vector2.up * jumpForce);
grounded = false;
doubleJumpReady = true;
}
else if (!grounded && doubleJumpReady)
{
rb.AddForce(Vector2.up * jumpForce);
doubleJumpReady = false;
}
}
Hope it works ;).
EDIT: grounded is set by overlapping spheres. Therefore no need to set it here. Use this code and press your jump btn 2 times and see if the Debug.Log message shows up. Also, your player ID (idx is not needed.) As far as i can see your script is attached two to different objects. Therefore their variables are not shared anyways.
protected void Jump()
{
if (grounded)
{
rb.AddForce(Vector2.up * jumpForce);
doubleJumpReady = true;
}
else if (!grounded && doubleJumpReady)
{
rb.AddForce(Vector2.up * jumpForce);
doubleJumpReady = false;
Debug.Log("I am double jumping");
}
}
And the final problem is, you do not execute one of your jumps you execute both at once. THis happens due to your execution.
Input.GetKey(KeyCode.UP)
instead use:
Input.GetKeyDown(KeyCode.Up);
GetKeyDown returns true when the button is pressed. GetKey returns true WHILE the button is pressed.
Hope it works now ;)
Upvotes: 2
Reputation: 889
I would implement it with a counter, you can set the number of jumps you want.
The code would be like this:
jumpCount = 0;
protected void Jump()
{
if(!grounded && jumpCount < 2)
{
jumpCount++;
rb.AddForce(Vector2.up * jumpForce);
}
if(grounded)
jumpCount = 0;
}
Upvotes: 1