Reputation: 33
I just started using Unity am trying to make a simple 3D platformer, before I can get to that, I need to get movement down. My problem comes in when the player jumps. When they jump, they can jump in the air as much as they want. I want it to only jump once. Can anybody help?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Playermovement : MonoBehaviour
{
public Rigidbody rb;
void Start ()
}
void Update()
{
bool player_jump = Input.GetButtonDown("DefaultJump");
if (player_jump)
{
rb.AddForce(Vector3.up * 365f);
}
}
}
}
Upvotes: 3
Views: 3768
Reputation: 125275
You can use a flag to detect when the player is touching the ground then only jump the player is touching the floor. This can be set to true
and false
in the OnCollisionEnter
and OnCollisionExit
functions.
Create a tag named "Ground" and make the GameObjects use this tag then attach the modified code below to the player that is doing the jumping.
private Rigidbody rb;
bool isGrounded = true;
public float jumpForce = 20f;
void Start()
{
rb = GetComponent<Rigidbody>();
}
private void Update()
{
bool player_jump = Input.GetButtonDown("DefaultJump");
if (player_jump && isGrounded)
{
rb.AddForce(Vector3.up * jumpForce);
}
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = true;
}
}
void OnCollisionExit(Collision collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = false;
}
}
Sometimes, using OnCollisionEnter
and OnCollisionExit
may not be fast enough. This is rare but possible. If you run into this then use Raycast with Physics.Raycast
to detect the floor. Make sure to throw the ray to the "Ground" layer only.
private Rigidbody rb;
public float jumpForce = 20f;
void Start()
{
rb = GetComponent<Rigidbody>();
}
private void Update()
{
bool player_jump = Input.GetButtonDown("DefaultJump");
if (player_jump && IsGrounded())
{
rb.AddForce(Vector3.up * jumpForce);
}
}
bool IsGrounded()
{
RaycastHit hit;
float raycastDistance = 10;
//Raycast to to the floor objects only
int mask = 1 << LayerMask.NameToLayer("Ground");
//Raycast downwards
if (Physics.Raycast(transform.position, Vector3.down, out hit,
raycastDistance, mask))
{
return true;
}
return false;
}
Upvotes: 5