Guest User

code

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