I am having an issue where when I hit space to jump, the jump will only work (as in, launch player straight up into the air) only if I am (1) on flat ground (moving or standing still), (2) on a downward slope, or (3) on an upward slope and standing still.
If I am on an upward slope and moving forward, the jump will slide my character fast up the ramp, rather than launching character upwards into air. So, the character's feet never visibly leave the ground.
Is the reason for this apparent within my controller code?
Thank you.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public Rigidbody r;
public CapsuleCollider capsule;
public Transform cameraTransform;
//Movement States
public MovementState state;
public enum MovementState
{
walking,
sprinting,
air
}
[Header("Keybinds")]
public KeyCode jumpKey = KeyCode.Space;
public KeyCode sprintKey = KeyCode.LeftShift;
[Header("Base Movement")]
public float horizontalInput;
public float verticalInput;
public Vector3 moveDirection;
public Vector3 moveDirectionRaw;
public int rotDegPerSecond = 720;
//Walking and Running
public float speed;
public float maxSpeed;
public float sprintSpeed;
public float walkSpeed;
//Jumping
public float jumpForce;
public bool jumpPressed;
public float stepsSinceLastJump;
//Falling
public bool isFalling;
public float clampYValue;
//Clamp Speed
public float clampXZValue;
[Header("Ground Checking")]
public LayerMask groundLayerMask;
public Transform groundCheckTransform;
public bool isGrounded;
public float groundCheckRadius = 0.25f;
public float distanceToGround;
void Awake()
{
r = GetComponent<Rigidbody>();
capsule = GetComponent<CapsuleCollider>();
}
private void MyInput()
{
horizontalInput = Input.GetAxis("Horizontal");
verticalInput = Input.GetAxis("Vertical");
moveDirection = new Vector3(horizontalInput, 0.0f, verticalInput).normalized;
moveDirection = (Quaternion.AngleAxis(cameraTransform.rotation.eulerAngles.y, Vector3.up) * moveDirection).normalized;
moveDirectionRaw = new Vector3(Input.GetAxisRaw("Horizontal"), 0.0f, Input.GetAxisRaw("Vertical")).normalized;
moveDirectionRaw = (Quaternion.AngleAxis(cameraTransform.rotation.eulerAngles.y, Vector3.up) * moveDirectionRaw).normalized;
//Jump
if (Input.GetKeyDown(jumpKey))
{
stepsSinceLastJump = 0;
jumpPressed = true;
}
}
void Update()
{
MyInput();
StateHandler();
UpdateState();
}
private void FixedUpdate()
{
Move();
FallCheck();
if (jumpPressed)
{
if (isGrounded)
{
Vector3 yVelocityZerod = new Vector3(r.velocity.x, 0, r.velocity.z);
r.velocity = yVelocityZerod;
//r.velocity = Vector3.zero;
r.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
jumpPressed = false;
}
}
GroundStopSlide();
GroundCheck();
}
void Move()
{
if (moveDirectionRaw != Vector3.zero && moveDirection != Vector3.zero)
{
Quaternion targetRotation = Quaternion.LookRotation(moveDirection); //or moveDirectionRaw
targetRotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotDegPerSecond * Time.deltaTime);
r.MoveRotation(targetRotation);
}
Vector3 force = moveDirection * speed;
r.AddForce(force, ForceMode.VelocityChange);
//Clamping Velocity
Vector3 velocityH = new Vector3(r.velocity.x, 0, r.velocity.z);
Vector3 velocityV = new Vector3(0, r.velocity.y, 0);
if (!isFalling && stepsSinceLastJump > 20)
{
r.velocity = Vector3.ClampMagnitude(velocityH, clampXZValue) + velocityV;
}
else
{
r.velocity = Vector3.ClampMagnitude(velocityH, clampXZValue) + velocityV;
}
}
void UpdateState()
{
stepsSinceLastJump += 1;
}
void GroundStopSlide()
{
if (moveDirectionRaw == Vector3.zero)
{
Vector3 zeroMe = new Vector3(0, r.velocity.y, 0);
r.velocity = zeroMe;
}
}
public void GroundCheck()
{
isGrounded = Physics.CheckSphere(groundCheckTransform.position, groundCheckRadius, groundLayerMask);
RaycastHit groundHit = new RaycastHit();
if (Physics.Raycast(transform.position, -Vector3.up, out groundHit))
{
distanceToGround = groundHit.distance;
}
}
private void StateHandler()
{
//Mode - Sprinting
if (isGrounded && Input.GetKey(sprintKey))
{
state = MovementState.sprinting;
speed = sprintSpeed;
}
//Mode - Walking
else if (isGrounded)
{
state = MovementState.walking;
speed = walkSpeed;
}
//Mode - Air
else
{
state = MovementState.air;
}
}
void FallCheck()
{
if (r.velocity.y < -0.01)
{
isFalling = true;
}
else
{
isFalling = false;
}
}
}
clampXZValuelimit. As soon as you jump, the ground no longer provides that resistance, and you can rocket sideways along the ramp as fast as your jump gives you elevation. To test this idea, try greatly reducing thespeedandclampXZValueparameters, to see if you can get some visible separation from the slope (rising faster than you move sideways). \$\endgroup\$