When sprinting the character goes trough walls.
Anyone have a fix?
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
public class PlayerMovementController : MonoBehaviour
{
[Header("Movement Settings")]
public float moveSpeed = 5f;
public float crouchSpeed = 2f;
public float sprintSpeed = 10f;
public float jumpForce = 10f;
public float sprintDuration = 6f;
public float sprintCooldown = 3f;
private bool isGrounded;
private bool isCrouching = false;
private bool isJumping = false;
private bool isSprinting = false;
private bool canSprint = true;
private Rigidbody rb;
private CapsuleCollider capsuleCollider;
private Camera mainCamera;
private Vector3 originalScale;
private void Start()
{
rb = GetComponent<Rigidbody>();
capsuleCollider = GetComponent<CapsuleCollider>();
rb.interpolation = RigidbodyInterpolation.Interpolate;
rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
rb.constraints = RigidbodyConstraints.FreezeRotation;
mainCamera = Camera.main;
originalScale = transform.localScale;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.LeftControl) && isGrounded)
{
ToggleCrouch();
}
if (Input.GetKey(KeyCode.LeftShift) && canSprint && !isSprinting)
{
StartCoroutine(Sprint());
}
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
Jump();
}
isJumping = !isGrounded;
}
private void FixedUpdate()
{
float speed = GetMovementSpeed();
Vector3 direction = GetMoveDirection();
float distanceToMove = speed * Time.fixedDeltaTime;
RaycastHit hit;
Vector3 nextPosition = rb.position + direction * distanceToMove;
if (Physics.SphereCast(rb.position, capsuleCollider.radius * 0.9f, direction, out hit, distanceToMove))
{
nextPosition = rb.position + direction * hit.distance;
if (Mathf.Abs(hit.normal.y) < 0.1f)
{
Vector3 remainingMovement = Vector3.ProjectOnPlane(direction, hit.normal);
nextPosition += remainingMovement * (distanceToMove - hit.distance);
}
}
rb.MovePosition(nextPosition);
}
public float GetMovementSpeed()
{
if (isCrouching)
{
return crouchSpeed;
}
else if (isSprinting)
{
return sprintSpeed;
}
else
{
return moveSpeed;
}
}
private Vector3 GetMoveDirection()
{
Vector3 cameraForward = mainCamera.transform.forward;
cameraForward.y = 0;
cameraForward.Normalize();
Vector3 cameraRight = mainCamera.transform.right;
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector3 moveDirection = (cameraForward * vertical) + (cameraRight * horizontal);
moveDirection.Normalize();
return moveDirection;
}
private void ToggleCrouch()
{
isCrouching = !isCrouching;
StartCoroutine(CrouchTransition());
}
IEnumerator CrouchTransition()
{
float targetHeight = isCrouching ? 0.5f : 1f;
float elapsedTime = 0f;
float transitionDuration = 0.2f;
Vector3 initialScale = transform.localScale;
while (elapsedTime < transitionDuration)
{
float t = elapsedTime / transitionDuration;
transform.localScale = Vector3.Lerp(initialScale, new Vector3(originalScale.x, targetHeight, originalScale.z), t);
elapsedTime += Time.deltaTime;
yield return null;
}
transform.localScale = new Vector3(originalScale.x, targetHeight, originalScale.z);
}
private void Jump()
{
if (isGrounded)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
isGrounded = false;
}
}
IEnumerator Sprint()
{
isSprinting = true;
yield return new WaitForSeconds(sprintDuration);
isSprinting = false;
canSprint = false;
yield return new WaitForSeconds(sprintCooldown);
canSprint = true;
}
public bool IsStandingStill()
{
return Mathf.Approximately(rb.velocity.magnitude, 0f) && !isJumping;
}
public bool IsJumping()
{
return isJumping;
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = true;
}
}
private void OnCollisionStay(Collision collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = true;
}
}
private void OnCollisionExit(Collision collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = false;
}
}
}