'Why can't I jump?
When I try to run this code on unity,everything works expect the jumping.Anyone know why?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
public float speed = 12f;
public float gravity = -9.81f;
public float jumpHeight;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
Vector3 velocity;
bool isGrounded;
// Update is called once per frame
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if(isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
if(Input.GetButtonDown("Jump") && isGrounded);
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity *Time.deltaTime);
}
}
Solution 1:[1]
For jumping in unity you can just add a Vector3 to the object you want to make jump, if it is in movement unity calculate automatic the trajectory of the object.
Solution 2:[2]
Your problem is with this line here
velocity.y += gravity * Time.deltaTime;
Don't try add gravity yourself, unity will be handing this for you if you have a character controller
Solution 3:[3]
As suggested in the comment, First make the isGrounded a little more stable.
Use the character's RigidBody and AddForce(Vector3 force, ForceMode mode = ForceMode.Force); to implement jumps, as a Jump is an impulsive force applied on the character in the up direction. Directly using Move is not the best way of implementing a jump force.
Solution 4:[4]
using System.Collections;
using System.Collections.Generic; // <-- Since these are not utilized and not necessary for this code, defined by being grey in their Colour.
// Consider Removing them, To stop using unnecessary Data / Library calls in your code
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
/* THINGS TO KNOW */
// Private - only members of this class have access.
// Public -can be accessed outside of the script.
// Public Static - can be accessed in other scripts by using ( nameOfTheScript.VariableFromThatScript ) which are called Pointers.
// Protected - means it's only available in the class itself and any child-class.
// [SerializeField] private - Means that the variable is no longer publicly accessible, but can still be accessed inside the Editor (Inspector) of Unity
// Giving you the chance to drag / drop your character controller and modify values of other variables (while not overwriting your values outside of your other scripts)
// Always define if your variable is Public / Private or Protected, by default they will be Public.
[SerializeField] private CharacterController controller;
[SerializeField] private float speed = 12f;
[SerializeField] private float gravity = -9.81f;
[SerializeField] private float jumpHeight; // !! On Default this Element is going to be 0, if Not Defined Within the Inspector !!!
[SerializeField] private Transform groundCheck;
[SerializeField] private float groundRadius = 0.4f; // groundDistance -> groundRadius ( As it defines the size of the Sphere made from GroundCheck element)
[SerializeField] private LayerMask groundMask;
private Vector3 velocity;
[SerializeField] private bool isGrounded;
void Update() // Called once per frame.
{
// Defines if the character IsGrounded ( True or False )
// 1) Find object groundCheck (dragged in the inspector for the code)
// .position Getting its position where GroundCheck is at the current moment
//,2) Make a Sphere with a radius of ..
// 3) Define what LayerMask is going to be checked.
isGrounded = Physics.CheckSphere(groundCheck.position, groundRadius, groundMask);
if (isGrounded && velocity.y < 0) // !! Issue fixed " if (isGrounded && velocity.y < 0); " You cannot have " ; " - breaker before your method brackets.
{
velocity.y = -2f;
}
/* Move these function into their separate methods.*/
/* Makes it easier to read as well as Debug,
in order to find where the issue in your code is taking place*/
Move();
Jump();
controller.Move(velocity * Time.deltaTime);
}
private void Move()
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
}
private void Jump()
{
// Y Axis
if (Input.GetButtonDown("Jump") && isGrounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime; // Applies gravity with (times) * Last updated frame to next update frame.
}
}
- Make sure that you add : LayerMask to your object as well from which you are trying to jump from and check if you can jump. Found on this Picture ->
LayerMask Applied to The Floor Or Ground Object
- On Player GameObject, Make sure that you have defined all variable values, as well as other GameObjects : such as " groundCheck " found on this Picture ->
Player Game Object Information In Inspector
- Last put not least make sure you have defined JumpHeight in your Inspector of the Player
- Though there are a lot of improvements still to make, this is what I would suggest, having provided you with commenting for Each Change or Explanation of a function.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | alex longo |
| Solution 2 | Jay |
| Solution 3 | varunkaustubh |
| Solution 4 |
