I'm currently working on a FPS "Speedrun" game & I want to add "Sliding" to the players movement. I already added "Crouching", but currently I'm stuck at getting the sliding done. (I'm using the Character Controller) I've tried many things, but nothing really worked. Heres the current PlayerMovement script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UIElements;
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
private Rigidbody rb;
public Transform cameraTransform;
public HeadBobController headBobController;
[Header("Movement")]
private float speedMultiplier = 1f;
public float speed = 12f;
public float sprintSpeed = 20f;
public float slopeSpeed = 0.01f;
public float gravity = -9.81f;
public float jumpHeight = 3f;
public float sensitivity = 2f;
public float cameraRotationLimit = 85f;
[Header("Countermovement")]
public float counterMovement = 0.175f;
private float threshold = 0.01f;
public float maxSlopeAngle = 35f;
[Header("Sliding / Crouch")]
public float slideSpeed;
float originalHeight;
public float reducedHeight;
float targetHeight = 2f;
public float timeToCrouch = 0.25f;
float timeElapsed = 0;
bool canStopCrouching;
bool wantStopCrouch;
bool isRunning = false;
public bool isCrouching = false;
bool canUseHeadbob = true;
bool WillSlideOnSlopes = true;
bool IsSliding
{
get
{
if (controller.isGrounded && Physics.Raycast(transform.position, Vector3.down, out RaycastHit slopeHit, 3f))
{
hitPointNormal = slopeHit.normal;
return Vector3.Angle(hitPointNormal, Vector3.up) > controller.slopeLimit;
} else
{
return false;
}
}
}
[Header("Headbob")]
[SerializeField] private float walkBobSpeed = 14f;
[SerializeField] private float walkBobAmount = 0.05f;
[SerializeField] private float sprintBobSpeed = 18f;
[SerializeField] private float sprintBobAmount = 0.11f;
[SerializeField] private float crouchBobSpeed = 8f;
[SerializeField] private float crouchBobAmount = 0.025f;
private float defaultYPos = 0;
private float timer;
private Vector3 hitPointNormal;
[Header("Ground Check")]
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
Vector3 velocity;
public bool isGrounded;
[Header("Camera")]
float cameraRotationX = 0f;
float cameraRotationY = 0f;
public Camera camera;
public Transform orientation;
[Header("Other")]
public GameObject speedlines;
public ParticleSystem jumpParticle;
void Start()
{
rb = GetComponent<Rigidbody>();
controller = GetComponent<CharacterController>();
originalHeight = controller.height;
defaultYPos = camera.transform.localPosition.y;
//Cursor.lockState = CursorLockMode.Locked;
//Cursor.visible = false;
}
public 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;
move = Vector3.ClampMagnitude(move, 1f);
if (Input.GetKey(KeyCode.LeftShift) && !isCrouching)
{
controller.Move(move * sprintSpeed * Time.deltaTime);
isRunning = true;
headBobController.amplitude = 0.1f;
headBobController.frequency = 30f;
} else
{
controller.Move(move * speed * speedMultiplier * Time.deltaTime);
isRunning = false;
headBobController.amplitude = 0.0426f;
headBobController.frequency = 19.1f;
}
if (Physics.Raycast(camera.transform.position, Vector3.up, 1f))
{
canStopCrouching = false;
} else
{
canStopCrouching = true;
}
if (canStopCrouching && wantStopCrouch && !Physics.Raycast(camera.transform.position, Vector3.up, 1f))
{
wantStopCrouch = false;
StopCrouch();
}
if (Input.GetKeyDown(KeyCode.LeftControl) && isGrounded)
{
//controller.height = Mathf.Lerp(reducedHeight, originalHeight, timeElapsed);
StartCrouch();
} else if(Input.GetKeyUp(KeyCode.LeftControl) && isGrounded && !Physics.Raycast(camera.transform.position, Vector3.up, 1f))
{
//controller.height = Mathf.Lerp(originalHeight, targetHeight, timeElapsed);
StopCrouch();
} else if(Input.GetKeyUp(KeyCode.LeftControl) && isGrounded && Physics.Raycast(camera.transform.position, Vector3.up, 1f))
{
wantStopCrouch = true;
}
if (Input.GetKey(KeyCode.LeftControl) && isRunning && isGrounded)
{
//Sliding
}
if (canUseHeadbob && isGrounded)
{
if (Mathf.Abs(move.x) > 0.1f || Mathf.Abs(move.z) > 0.1f)
{
timer += Time.deltaTime * (isCrouching ? crouchBobSpeed : isRunning ? sprintBobSpeed : walkBobSpeed);
camera.transform.localPosition = new Vector3(camera.transform.localPosition.x, defaultYPos + Mathf.Sin(timer) * (isRunning ? sprintBobAmount : walkBobAmount), camera.transform.localPosition.z);
}
}
if(WillSlideOnSlopes && IsSliding)
{
move += new Vector3(hitPointNormal.x, -hitPointNormal.y, hitPointNormal.z) * slopeSpeed;
}
if (isRunning)
{
speedlines.active = true;
} else {
speedlines.active = false;
}
controller.Move(move * speed * speedMultiplier * Time.deltaTime);
if (Input.GetButtonDown("Jump") && isGrounded)
{
controller.Move(-transform.forward * 0.1f);
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
jumpParticle.Play();
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
// Rotate the player based on mouse input
float mouseX = Input.GetAxis("Mouse X") * sensitivity;
float mouseY = Input.GetAxis("Mouse Y") * sensitivity;
cameraRotationY += mouseX;
cameraRotationX -= mouseY;
cameraRotationX = Mathf.Clamp(cameraRotationX, -cameraRotationLimit, cameraRotationLimit);
cameraTransform.localEulerAngles = new Vector3(cameraRotationX, cameraRotationY, 0f);
transform.eulerAngles = new Vector3(0f, cameraRotationY, 0f);
}
private void StartCrouch()
{
controller.height = reducedHeight;
speedMultiplier = 0.5f;
isCrouching = true;
}
private void StopCrouch()
{
controller.height = originalHeight;
speedMultiplier = 1f;
isCrouching = false;
}
}
It would be very nice if anyone could try to explain me how to implement it into this code using the Character Controller! :)
I've tried multiple Youtube Tutorial solutions & a lot in Online Forums, nothing really worked for me for some reason. Often the system wouldn't even work (nothing happened). I want the player to have the crouching ability (which is implemented) & to slide when isRunning & when the player isGrounded