I'm writing some code to create a Minecraft Quake like game but I have an issue with the jump mecanic. When I'm stuck to a wall the player jump to high (see the video).
I use a Rigidbody for the physics and I modify that velocity to move the player. There is a Physic Material on the player's Collider with no consideration for friction or bouncing.
If you have ideas to fix the bug or an alternative to work around the problem, I'm interested.
Here is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum PlayerMovementState {
Sneak,
Walk,
Run
}
public class PlayerControls : MonoBehaviour
{
Rigidbody rb;
Vector3 velocity, desiredVelocity;
PlayerMovementState moveState;
float groundDistance;
[SerializeField]
bool forwardAir, backAir, rightAir, leftAir;
[SerializeField]
LayerMask groundLayer;
[SerializeField]
bool onGround;
bool desiredJump;
float jumpHeight = 1.0f;
private void Awake() {
rb = GetComponent<Rigidbody>();
moveState = PlayerMovementState.Walk;
groundDistance = GetComponentInChildren<Collider>().bounds.extents.y;
}
private void Update() {
Vector2 playerInputs = Vector2.ClampMagnitude(
new Vector2(
Input.GetAxis("Horizontal"),
Input.GetAxis("Vertical")
), 1.0f
);
if (Input.GetKey(KeyCode.LeftShift)) moveState = PlayerMovementState.Sneak;
else if (Input.GetKey(KeyCode.LeftControl)) moveState = PlayerMovementState.Run;
else moveState = PlayerMovementState.Walk;
float speed = moveState == PlayerMovementState.Run ? 10f : (
moveState == PlayerMovementState.Sneak ? 2f : 5f
);
RaycastGround();
onGround = !forwardAir && !backAir && !rightAir && !leftAir;
if (Input.GetButtonDown("Jump")) desiredJump = true;
if (moveState == PlayerMovementState.Sneak)
{
if (forwardAir && playerInputs.y > 0) playerInputs.y = 0f;
if (backAir && playerInputs.y < 0) playerInputs.y = 0f;
if (rightAir && playerInputs.x > 0) playerInputs.x = 0f;
if (leftAir && playerInputs.x < 0) playerInputs.x = 0f;
}
desiredVelocity =
(transform.forward * playerInputs.y + transform.right * playerInputs.x) * speed;
}
private void FixedUpdate() {
velocity = rb.velocity;
float acceleration = 10;
velocity.x = Mathf.MoveTowards(velocity.x, desiredVelocity.x, acceleration);
velocity.z = Mathf.MoveTowards(velocity.z, desiredVelocity.z, acceleration);
if (desiredJump && onGround)
{
desiredJump = false;
float jumpSpeed = Mathf.Sqrt(-2f * Physics.gravity.y * jumpHeight);
velocity.y += jumpSpeed;
}
rb.velocity = velocity;
desiredJump = false;
}
void RaycastGround()
{
forwardAir = !(Physics.Raycast(
transform.position + Vector3.forward * 0.1f,
-Vector3.up,
groundDistance + 0.1f,
groundLayer
));
backAir = !(Physics.Raycast(
transform.position - Vector3.forward * 0.1f,
-Vector3.up,
groundDistance + 0.1f,
groundLayer
));
rightAir = !(Physics.Raycast(
transform.position + Vector3.right * 0.1f,
-Vector3.up,
groundDistance + 0.1f,
groundLayer
));
leftAir = !(Physics.Raycast(
transform.position - Vector3.right * 0.1f,
-Vector3.up,
groundDistance + 0.1f,
groundLayer
));
}
}