Guest User

code

a guest
Jul 21st, 2025
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.38 KB | None | 0 0
  1. // Movement_Player.cs
  2. using TMPro;
  3. using UnityEngine;
  4. using UnityEngine.InputSystem;
  5. using UnityEngine.UI;
  6. using System.Collections;
  7. using System;
  8. using System.Runtime.CompilerServices;
  9.  
  10. public class Movement_Player : MonoBehaviour
  11. {
  12. // ───────────────────────────────── Player Settings ─────────────────────────────────
  13. [Header("Movement Settings")]
  14. public float walkSpeed = 4f;
  15. public float sprintSpeed = 6f;
  16. public float crouchSpeed = 2f;
  17. public float crouchHeight = 0.5f;
  18. public float slideSpeed = 10f;
  19. public float airControl = 0.5f;
  20. public float groundBrakeSpeed = 10f; // just for smoothing the stopping phase of character
  21. public float jumpfactor = 1f;
  22. public float gravity = -20;
  23. public float jumpSlopeAngleThreshold = 25f; // Angle in degrees to consider a slope for jumping
  24. public enum CrouchMode
  25. {
  26. Toggle,
  27. Hold
  28. }
  29. public CrouchMode crouchMode = CrouchMode.Toggle; // Toggle or Hold
  30. public float thresholdSlideSpeed = 4f; // Speed threshold to start sliding
  31. public float steepSlopeThreshold = 15f; // Angle in degrees to consider a slope steep
  32. public float slideTimeOnGround = 0.5f; // Time to slide on ground before stopping
  33. public float SlopeSlideForceFactor = 30f; // Factor to apply when sliding down a slope
  34. public float slideHeight = 0.25f;
  35. [Header("Camera Settings")]
  36. public float minViewAngle = -45f;
  37. public float maxViewAngle = 45f;
  38. public float sens = 1f;
  39. public float smoothTime = 0.05f;
  40. public float transitionSpeed = 0.7f;
  41. public Camera playerCamera;
  42.  
  43. [Header("Debug ")]
  44. public TextMeshProUGUI debugText1;
  45. public TextMeshProUGUI debugText2;
  46. public TextMeshProUGUI debugText3;
  47. public Button resetButton;
  48. public float calculatedSlideSpeed = 0f;
  49.  
  50. // ───────────────────────────────── Runtime Variables ─────────────────────────────────
  51. private CharacterController characterController;
  52. private Vector2 input = Vector2.zero;
  53. private Vector2 look = Vector2.zero;
  54. private Vector2 smoothedLookInput;
  55. private float pitch = 0f;
  56.  
  57. private bool isSprinting = false;
  58. private bool isJumping = false;
  59. private bool isMovingForward = false;
  60. private bool isCrouching = false;
  61. private bool isSliding = false;
  62. private float originalHeight = 0f;
  63. private int crouchCounter = 0;
  64. public float slopeAngle = 0f;
  65. private float slideTimer = 0f;
  66. private Vector3 slopeDir = Vector3.zero;
  67. private Vector3 slopeNormal = Vector3.up;
  68. private float speed = 0f;
  69.  
  70. private Vector3 velocity = Vector3.zero;
  71. private Vector3 horizontalVelocity = Vector3.zero;
  72. private Vector3 currentVelocity = Vector3.zero;
  73. private Vector3 lastPosition = Vector3.zero;
  74. private float velAvg = 0f;
  75. private float totalDistance = 0f;
  76. private float totalTime = 0f;
  77.  
  78. // ───────────────────────────────── Unity Methods ─────────────────────────────────
  79.  
  80. void Start()
  81. {
  82. characterController = GetComponent<CharacterController>();
  83. Cursor.lockState = CursorLockMode.Locked;
  84. Cursor.visible = false;
  85. lastPosition = transform.position;
  86.  
  87. if (resetButton != null)
  88. {
  89. resetButton.onClick.AddListener(() =>
  90. {
  91. totalDistance = 0f;
  92. totalTime = 0f;
  93. velAvg = 0f;
  94. });
  95. }
  96. originalHeight = playerCamera.transform.localPosition.y;
  97. }
  98.  
  99. void Update()
  100. {
  101. HandleJump();
  102. HandleSlopes();
  103. ApplyGravity();
  104. AdjustVelocityToSlope();
  105. HandleSlide();
  106. HandleMovement();
  107. characterController.Move(velocity * Time.deltaTime);
  108. }
  109.  
  110. void LateUpdate()
  111. {
  112. UpdateCamera();
  113. UpdateDebug();
  114. }
  115.  
  116. // ───────────────────────────────── Movement ─────────────────────────────────
  117.  
  118. void HandleMovement()
  119. {
  120. Vector3 moveInput = transform.right * input.x + transform.forward * input.y;
  121. if (moveInput.magnitude > 1f) moveInput.Normalize();
  122.  
  123. float forwardAmount = Vector3.Dot(moveInput.normalized, transform.forward);
  124. bool isMovingForward = forwardAmount > 0.7f;
  125.  
  126. speed =
  127. (isSliding && horizontalVelocity.magnitude >= thresholdSlideSpeed) ? calculatedSlideSpeed :
  128. (isCrouching) ? crouchSpeed :
  129. (isSprinting && isMovingForward) ? sprintSpeed :
  130. walkSpeed;
  131.  
  132. Vector3 desiredVelocity = moveInput * speed;
  133.  
  134. if (characterController.isGrounded)
  135. {
  136. if (input == Vector2.zero)
  137. horizontalVelocity = Vector3.Lerp(horizontalVelocity, Vector3.zero, groundBrakeSpeed * Time.deltaTime);
  138. else
  139. horizontalVelocity = desiredVelocity;
  140. }
  141. else
  142. {
  143. float lerpFactor = Mathf.Clamp01(airControl * Time.deltaTime);
  144. horizontalVelocity = Vector3.Lerp(horizontalVelocity, desiredVelocity, lerpFactor);
  145. }
  146. }
  147.  
  148. void HandleJump()
  149. {
  150. isMovingForward = Vector3.Dot(-slopeDir, transform.forward) > 0.7f;
  151.  
  152. if (slopeAngle > jumpSlopeAngleThreshold && isMovingForward)
  153. {
  154. // Don't allow jumping on steep slopes
  155. isJumping = false;
  156. return;
  157. }
  158. if (characterController.isGrounded && velocity.y < 0)
  159. velocity.y = -2f; // Stick to ground
  160.  
  161. if (isJumping && characterController.isGrounded)
  162. {
  163. velocity.y += Mathf.Sqrt(jumpfactor * -2f * gravity);
  164. }
  165. }
  166.  
  167. void HandleSlide()
  168. {
  169. if (isSliding && horizontalVelocity.magnitude >= thresholdSlideSpeed && characterController.isGrounded)
  170. {
  171. isCrouching = false;
  172.  
  173. float slopeMultiplier = 1f + (Mathf.Clamp(-slopeAngle, 15f, 75f) - 15f) / 30f;
  174. calculatedSlideSpeed = slideSpeed * slopeMultiplier;
  175.  
  176. if (Math.Abs(slopeAngle) < steepSlopeThreshold)
  177. {
  178. isSliding = true;
  179. slideTimer += Time.deltaTime;
  180. if (slideTimer >= slideTimeOnGround)
  181. {
  182. isSliding = false;
  183. slideTimer = 0f;
  184. }
  185. return;
  186. }
  187. else if (slopeAngle > 0)
  188. {
  189. isSliding = false;
  190. slideTimer = 0f;
  191. return;
  192. }
  193. else
  194. {
  195. isSliding = true;
  196. slideTimer = 0f;
  197. }
  198.  
  199. // Slide vector, projected onto slope
  200. Vector3 rawSlide = slopeDir * calculatedSlideSpeed * Time.deltaTime;
  201. Vector3 adjustedSlide = Vector3.ProjectOnPlane(rawSlide, slopeNormal); // Keeps you stuck to slope
  202.  
  203. // FIX: Only modify horizontal velocity, don't overwrite entire velocity
  204. horizontalVelocity += new Vector3(adjustedSlide.x, 0f, adjustedSlide.z);
  205. }
  206. else if (isSliding)
  207. {
  208. // FIX: Stop sliding if conditions aren't met
  209. isSliding = false;
  210. slideTimer = 0f;
  211. }
  212. }
  213.  
  214.  
  215. void HandleSlopes()
  216. {
  217. if (Physics.Raycast(transform.position, Vector3.down, out RaycastHit hit, 2f))
  218. {
  219. Vector3 slopeNormalHit = hit.normal;
  220. slopeNormal = slopeNormalHit;
  221.  
  222. float angle = Vector3.Angle(Vector3.up, slopeNormal);
  223.  
  224. slopeDir = Vector3.ProjectOnPlane(Vector3.down, slopeNormal).normalized;
  225.  
  226. float alignment = Vector3.Dot(transform.forward, slopeDir);
  227.  
  228. slopeAngle = angle * -Mathf.Sign(alignment);
  229. }
  230. else
  231. {
  232. slopeAngle = 0f;
  233. }
  234. }
  235.  
  236. void ApplyGravity()
  237. {
  238. velocity.y += gravity * Time.deltaTime;
  239. velocity = new Vector3(horizontalVelocity.x, velocity.y, horizontalVelocity.z);
  240. }
  241.  
  242. void AdjustVelocityToSlope()
  243. {
  244. if (!characterController.isGrounded) return;
  245.  
  246. Vector3 moveDir = new Vector3(velocity.x, 0f, velocity.z);
  247. Vector3 slopeMove = Vector3.ProjectOnPlane(moveDir, slopeNormal);
  248.  
  249. if (Mathf.Abs(slopeAngle) > steepSlopeThreshold && !isJumping)
  250. {
  251. Vector3 slideDir = Vector3.ProjectOnPlane(Vector3.down, slopeNormal).normalized;
  252. velocity += slideDir * slideSpeed;
  253. }
  254. else
  255. {
  256. velocity = new Vector3(slopeMove.x, velocity.y, slopeMove.z);
  257. }
  258. }
  259.  
  260. // ───────────────────────────────── Camera ─────────────────────────────────
  261.  
  262. void UpdateCamera()
  263. {
  264. smoothedLookInput = Vector2.Lerp(smoothedLookInput, look, smoothTime);
  265.  
  266. float mouseX = smoothedLookInput.x * sens * Time.deltaTime;
  267. float mouseY = smoothedLookInput.y * sens * Time.deltaTime;
  268.  
  269. transform.Rotate(Vector3.up * mouseX);
  270. pitch -= mouseY;
  271. pitch = Mathf.Clamp(pitch, minViewAngle, maxViewAngle);
  272. playerCamera.transform.localRotation = Quaternion.Euler(pitch, 0f, 0f);
  273. }
  274.  
  275. void UpdateCameraDuringMotionStates()
  276. {
  277. if (isSliding)
  278. {
  279. playerCamera.transform.localPosition =
  280. Vector3.Lerp(playerCamera.transform.localPosition,
  281. new Vector3(0f, slideHeight, 0f),
  282. Time.deltaTime * transitionSpeed);
  283. }
  284. else if (isCrouching)
  285. {
  286. playerCamera.transform.localPosition =
  287. Vector3.Lerp(playerCamera.transform.localPosition,
  288. new Vector3(0f, crouchHeight, 0f),
  289. Time.deltaTime * transitionSpeed);
  290. }
  291. else
  292. {
  293. playerCamera.transform.localPosition =
  294. Vector3.Lerp(playerCamera.transform.localPosition,
  295. new Vector3(0f, originalHeight, 0f),
  296. Time.deltaTime * transitionSpeed);
  297. }
  298. }
  299.  
  300. // ───────────────────────────────── Debug ─────────────────────────────────
  301.  
  302. void UpdateDebug()
  303. {
  304. currentVelocity = (transform.position - lastPosition) / Time.deltaTime;
  305.  
  306. if (currentVelocity.magnitude > 0f)
  307. {
  308. totalDistance += currentVelocity.magnitude * Time.deltaTime;
  309. totalTime += Time.deltaTime;
  310. }
  311.  
  312. velAvg = totalDistance / Mathf.Max(totalTime, 0.01f);
  313. lastPosition = transform.position;
  314.  
  315. Debug.Log(currentVelocity.y);
  316.  
  317. if (debugText1 != null) debugText1.text = "Current Vel: " + currentVelocity.ToString("F2") + " m/s";
  318. if (debugText2 != null) debugText2.text = "Avg Vel: " + velAvg.ToString("F2") + " m/s";
  319.  
  320. //if (debugText1 != null) debugText1.text = isSliding ? "Sliding" : "";
  321. //if (debugText2 != null) debugText2.text = isCrouching ? "Crouching" : "";
  322. //if (debugText3 != null) debugText3.text = isSprinting ? "Walking/ Sprinting" : "";
  323.  
  324. //Debug.Log(GetRealisticSlideMultiplier(Mathf.Abs(slopeAngle)));
  325. }
  326.  
  327.  
  328. // ───────────────────────────────── Input Actions ─────────────────────────────────
  329.  
  330. public void Move(InputAction.CallbackContext context)
  331. {
  332. if (context.performed || context.canceled)
  333. input = context.ReadValue<Vector2>();
  334. }
  335.  
  336. public void Look(InputAction.CallbackContext context)
  337. {
  338. look = context.ReadValue<Vector2>() * sens;
  339. }
  340.  
  341. public void Jump(InputAction.CallbackContext context)
  342. {
  343. isJumping = context.performed;
  344. }
  345.  
  346. public void Sprint(InputAction.CallbackContext context)
  347. {
  348. isSprinting = context.performed;
  349. }
  350.  
  351. public void Crouch(InputAction.CallbackContext context)
  352. {
  353. if (context.started && crouchMode == CrouchMode.Toggle)
  354. {
  355. crouchCounter++;
  356. crouchCounter %= 2; // Toggle between 0 and 1
  357.  
  358. if (crouchCounter == 1)
  359. isCrouching = true;
  360. else
  361. isCrouching = false;
  362. isSliding = true;
  363. return;
  364. }
  365. else if (context.performed && crouchMode == CrouchMode.Hold)
  366. isCrouching = true;
  367. else if (context.canceled && crouchMode == CrouchMode.Hold)
  368. isCrouching = false;
  369. }
  370.  
  371. // ───────────────────────────────── Misc ─────────────────────────────────
  372. }
Advertisement
Add Comment
Please, Sign In to add comment