public bool useCharacterForward = false;
public bool lockToCameraForward = false;
public float turnSpeed = 10f;
public KeyCode sprintJoystick = KeyCode.JoystickButton2;
public KeyCode sprintKeyboard = KeyCode.Space;
public bool useJump = false;
public Vector3 jump;
public float jumpImpulse;
private float turnSpeedMultiplier;
private float speed = 0f;
private float direction = 0f;
private bool isSprinting = false;
private Animator anim;
private Vector3 targetDirection;
private Vector2 input;
private Quaternion freeRotation;
private Camera mainCamera;
private float velocity;
private bool isGrounded;
private Rigidbody rb;
// Use this for initialization
void Start()
{
anim = GetComponent<Animator>();
mainCamera = Camera.main;
rb = GetComponent<Rigidbody>();
jump = new Vector3(0.0f, 2.0f, 0.0f);
}
private void OnCollisionStay(Collision collision)
{
if (collision.gameObject.tag == "Ground")
{
isGrounded = true;
}
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && isGrounded && useJump)
{
rb.AddForce(jump * jumpImpulse, ForceMode.Impulse);
isGrounded = false;
}
}
Even if the player is in the air and the even if I'm checking for the ground tag I can still press on space once more while the player is in the air after jumping and it will make a jump and move the player higher in the air.
but I'm setting the isGround to false and the player is much higher above the ground and still pressing space make it jumping in the air while in the air already.
This screenshot show how the ground object is built in the hierarchy. The player have a capsule collider and a rigidbody.
There are 3 floor objects :
CodePudding user response:
The physics (Rigidbody) are only updated in FixedUpdate
. Also OnCollisionStay
is called within that FixedUpdate
cycle for each collider.
In your setup there is a little chance left that OnCollisionStay
is being fired once more after your first press and sets the isGrounded
again to true
, allowing you one additional jump later.
I think it would already prevent that case if you moved the jump to either FixedUpdate
or even the OnCollisonStay
itself:
private bool isJump;
private bool isGrounded;
private void OnCollisionStay(Collision collision)
{
// In general rather use CompareTag instead of ==
// It causes an error If the tag is non-existent or has a typo making
// your debugging way easier and is also slightly more efficient
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = true;
}
}
private FixedUdpate()
{
// Should we jump?
if(isJump && isGrounded)
{
rb.AddForce(jump * jumpImpulse, ForceMode.Impulse);
isGrounded = false;
}
isJump = false;
}
private void Update()
{
// As you already did correctly get single event user input in Update
// in order to not miss one
// I would check the cheaper bool flag first
if (isGrounded && useJump && Input.GetKeyDown(KeyCode.Space))
{
isJump = true;
}
}
This now should make sure that a jump can only be applied while colliding with the ground