Hello!
I seem to run into a couple of issues with my script here, any tips would be appreciated!
- Character still seems to clamp near the top of a wall while jumping and is able to climb onto the object.
- While moving and jumping, if character hits a platform with his head, the Y movement is stopped and instantly falls. However, when the character is jumping while standing still, he still sticks to the ceiling for a brief second.
- Character is able to un-crouch under a platform, what would be a decent solution to this?
- I am still in the earlier stages of learning, any tips on to clean up my code are also helpful
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
[SerializeField] private float walkSpeed, runSpeed, sprintSpeed;
[SerializeField] private float runBuildUpSpeed;
[SerializeField] private float originalHeight;
[SerializeField] private float crouchHeight = 0.5f;
private float movementSpeed;
[SerializeField] private float slopeForce;
[SerializeField] private float slopeForceRayLength;
private CharacterController charController;
[SerializeField] private AnimationCurve jumpFallOff;
[SerializeField] private float jumpMultiplier;
private bool isJumping = false;
private bool isSprinting = false;
private bool isWalking = false;
private bool isCrouching = false;
[SerializeField] KeyCode jumpKey;
[SerializeField] KeyCode sprintKey;
[SerializeField] KeyCode walkKey;
[SerializeField] KeyCode crouchKey;
// Start is called before the first frame update
private void Start()
{
charController = GetComponent<CharacterController>();
originalHeight = charController.height;
}
// Update is called once per frame
private void Update()
{
PlayerMovement();
}
private void PlayerMovement()
{
// Check movement and speed
float xInput = Input.GetAxis("Horizontal");
float zInput = Input.GetAxis("Vertical");
Vector3 forwardMovement = transform.forward * zInput;
Vector3 rightMovement = transform.right * xInput;
charController.SimpleMove(Vector3.ClampMagnitude(forwardMovement + rightMovement, 1.0f) * movementSpeed);
//Clamp to slopes
if((xInput != 0 || zInput !=0) && onSlope())
{
charController.Move(Vector3.down * charController.height / 2 * slopeForce * Time.deltaTime);
}
SetMovementSpeed();
JumpInput();
}
private void SetMovementSpeed()
{
SprintInput();
WalkInput();
CrouchInput();
}
private void SprintInput()
{
if(Input.GetKey(sprintKey) && !isWalking && !isCrouching && Input.GetKey(KeyCode.W))
{
isSprinting = true;
movementSpeed = Mathf.Lerp(movementSpeed, sprintSpeed, Time.deltaTime * runBuildUpSpeed);
}
else
{
isSprinting = false;
movementSpeed = Mathf.Lerp(movementSpeed, runSpeed, Time.deltaTime * runBuildUpSpeed);
}
}
private void WalkInput()
{
if(Input.GetKey(walkKey) && !isSprinting)
{
isWalking = true;
movementSpeed = Mathf.Lerp(movementSpeed, walkSpeed, Time.deltaTime * 100);
}
else
{
isWalking = false;
movementSpeed = Mathf.Lerp(movementSpeed, runSpeed, Time.deltaTime * runBuildUpSpeed);
}
}
private void CrouchInput()
{
if(Input.GetKey(crouchKey))
{
isCrouching = true;
charController.height = crouchHeight;
}
else
{
isCrouching = false;
charController.height = Mathf.Lerp(charController.height, originalHeight, Time.deltaTime * 30);
}
}
private bool onSlope()
{
if (isJumping)
return false;
RaycastHit hit;
if(Physics.Raycast(transform.position, Vector3.down, out hit, charController.height / 2 * slopeForceRayLength))
if(hit.normal != Vector3.up)
return true;
return false;
}
private void JumpInput()
{
if(Input.GetKeyDown(jumpKey) && !isJumping)
{
isJumping = true;
StartCoroutine(JumpEvent());
}
}
private IEnumerator JumpEvent()
{
charController.slopeLimit = 90.0f;
float timeInAir = 0.0f;
do
{
float jumpForce = jumpFallOff.Evaluate(timeInAir);
charController.Move(Vector3.up * jumpForce * jumpMultiplier * Time.deltaTime);
timeInAir += Time.deltaTime;
yield return null;
} while (!charController.isGrounded && charController.collisionFlags != CollisionFlags.Above);
charController.slopeLimit = 45.0f;
isJumping = false;
}
}