Guest User

Untitled

a guest
Apr 16th, 2026
28
0
171 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.21 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using UnityEngine;
  5. using UnityEngine.Events;
  6. using UnityEngine.ProBuilder.MeshOperations;
  7.  
  8. public class PlayerMovement : MonoBehaviour
  9. {
  10. public float gravity = -13f;
  11.  
  12. public float velocityY = 0f;
  13.  
  14. [SerializeField] Transform orientation;
  15.  
  16. [Header("Movement")]
  17. public float moveSpeed = 6f;
  18. [SerializeField] float airMultiplier = 0.4f;
  19. float movementMultiplier = 10f;
  20.  
  21. [Header("Sprinting")]
  22. public float walkSpeed = 4f;
  23. [SerializeField] float crouchSpeed = 4f;
  24. [SerializeField] float sprintSpeed = 6f;
  25. [SerializeField] float acceleration = 10f;
  26. // public AnimationCurve accelTest;
  27.  
  28. [HideInInspector] public float currentwalkSpeed = 0f;
  29. float currentcrouchSpeed = 0f;
  30. float currentsprintSpeed = 0f;
  31. CrouchScript crouchScript;
  32.  
  33. [Header("Jumping")]
  34. public float jumpForce = 5f;
  35.  
  36. float currentjumpForce;
  37.  
  38. [Header("Keybinds")]
  39. [SerializeField] KeyCode sprintKey = KeyCode.LeftShift;
  40.  
  41. [Header("Drag")]
  42. [SerializeField] float groundDrag = 6f;
  43. [SerializeField] float airDrag = 2f;
  44.  
  45. Vector2 movementInput;
  46.  
  47. [Header("Ground Detection")]
  48. [SerializeField] Transform groundCheck;
  49. [SerializeField] LayerMask groundMask;
  50. [SerializeField] float groundDistance = 0.2f;
  51. [Range(0.125f, 1f)]
  52. [SerializeField] float stairHeight = 0.35f;
  53. public bool isGrounded { get; private set; }
  54. bool isSprinting = false;
  55.  
  56. [HideInInspector] public Vector3 moveDirection;
  57. Vector3 slopeMoveDirection;
  58.  
  59. [HideInInspector] public Rigidbody rb;
  60.  
  61. float slopeSpeedMult = 1.25f;
  62.  
  63. RaycastHit slopeHit;
  64.  
  65. public float currentStamina;
  66. float staminaLostRate = 0f;
  67. float maxStamina = 100;
  68. bool startStaminaRegain = false;
  69.  
  70. [Header("Movement Helpers")]
  71. public float coyoteTime = 0.2f;
  72. float currentCoyoteTime = 0f;
  73. public float inputBufferTime = 0.1f;
  74. bool jumpBuffered = false;
  75. public float monkeyBoostAirDrag = 1.5f;
  76.  
  77. // CrouchScript crouchRef;
  78.  
  79. [HideInInspector] public KeyCode forwardKey = KeyCode.W;
  80. [HideInInspector] public KeyCode backKey = KeyCode.S;
  81. [HideInInspector] public KeyCode leftKey = KeyCode.A;
  82. [HideInInspector] public KeyCode rightKey = KeyCode.D;
  83. [HideInInspector] public KeyCode crouchKey = KeyCode.C;
  84. [HideInInspector] public KeyCode jumpKey = KeyCode.Space;
  85.  
  86. [Header("Monky Stuff")]
  87. public float monkeyBoostCooldown = 5f; // Time you have to sprint to recharge monkey boost.
  88. float currentMonkeyBoostTime;
  89. public float forwardLeapForce = 5;
  90. public float upwardLeapForce = 20f;
  91.  
  92. [HideInInspector] public bool monkeyBoostAvailable = true;
  93. [HideInInspector] public bool isMonkeyBoosting = false;
  94. [HideInInspector] public UnityEvent onMonkeyBoostReady;
  95. [HideInInspector] public UnityEvent onMonkeyBoost;
  96.  
  97. bool readyingBoost;
  98. private void Start()
  99. {
  100. rb = GetComponent<Rigidbody>();
  101. crouchScript = GetComponent<CrouchScript>();
  102. rb.freezeRotation = true;
  103. currentwalkSpeed = walkSpeed;
  104. currentcrouchSpeed = crouchSpeed;
  105. currentsprintSpeed = sprintSpeed;
  106. currentjumpForce = jumpForce;
  107. currentStamina = maxStamina;
  108. currentCoyoteTime = coyoteTime;
  109. StartCoroutine(monkeyBoostTimer());
  110. // crouchRef = GetComponent<CrouchScript>();
  111. }
  112.  
  113. private void Update()
  114. {
  115. isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
  116. // isGrounded = Physics.SphereCast(groundCheck.position, 0.25f, groundCheck.up * -1f, out, groundDistance, groundMask);
  117.  
  118. MyInput();
  119. ControlDrag();
  120. ControlSpeed();
  121.  
  122. if (startStaminaRegain == true && isSprinting)
  123. {
  124. startStaminaRegain = false;
  125. StopCoroutine(regainStamina());
  126. }
  127. else if (startStaminaRegain == false && currentStamina < maxStamina && !isSprinting)
  128. {
  129. startStaminaRegain = true;
  130. StartCoroutine(regainStamina());
  131. }
  132.  
  133. if ((Input.GetKeyDown(jumpKey) && (isGrounded || currentCoyoteTime > 0)) || (isGrounded && jumpBuffered))
  134. {
  135. Jump();
  136. }
  137. else if (moveSpeed > walkSpeed && rb.velocity.magnitude >= 3f && monkeyBoostAvailable && Input.GetKey(KeyCode.LeftShift) && Input.GetKeyDown(KeyCode.X)) MonkeyBoost();
  138. else if (Input.GetKeyDown(jumpKey) && !jumpBuffered && !isGrounded)
  139. {
  140. StartCoroutine(JumpBuffer());
  141. }
  142.  
  143. // CheckForSteps();
  144. }
  145.  
  146. void CheckForSteps()
  147. {
  148. if(Physics.Raycast(transform.position + transform.forward * 0.525f, Vector3.down, out RaycastHit feetHit, 1.5f, groundMask) && !isStepping)
  149. {
  150. if(MovingTowardsPoint(feetHit.point) && (feetHit.point.y - groundCheck.position.y) >= 0.05f)
  151. {
  152. Debug.Log("STEPPING UP");
  153. StepUp(feetHit.point);
  154. }
  155. }
  156. }
  157.  
  158. private void FixedUpdate()
  159. {
  160. MovePlayer();
  161. }
  162.  
  163. private void OnCollisionEnter(Collision collision)
  164. {
  165. if (collision.collider.isTrigger || !isGrounded) return;
  166.  
  167. isMonkeyBoosting = false;
  168.  
  169. if (velocityY >= -5f) return;
  170.  
  171. StepUp(collision.GetContact(0).point);
  172. }
  173.  
  174. bool isStepping = false;
  175. void StepUp(Vector3 point)
  176. {
  177. if (moveDirection == Vector3.zero || isStepping || OnSlope()) return;
  178.  
  179. float difference = point.y - groundCheck.position.y;
  180.  
  181. if (difference < stairHeight && difference >= 0.05f)
  182. {
  183. // rb.MovePosition(transform.position + (moveDirection.normalized * 0.5f + new Vector3(0, difference + 0.1f, 0)));
  184. // rb.AddForce(moveDirection.normalized * 1.25f, ForceMode.VelocityChange);
  185. StartCoroutine(stepUp(difference));
  186. }
  187. }
  188.  
  189. IEnumerator stepUp(float difference)
  190. {
  191. isStepping = true;
  192. float stepTime = 0.1f;
  193.  
  194. while(stepTime > 0)
  195. {
  196. stepTime -= Time.deltaTime;
  197. if(!OnSlope())rb.MovePosition(transform.position + (moveDirection.normalized * 0.5f + new Vector3(0, difference + 0.1f, 0)) * (20f * Time.deltaTime));
  198. else rb.MovePosition(transform.position + (slopeMoveDirection.normalized * 0.5f + new Vector3(0, difference + 0.1f, 0)) * (25f * Time.deltaTime));
  199. yield return null;
  200. }
  201.  
  202. rb.AddForce(rb.velocity * 1.2f);
  203.  
  204. isStepping = false;
  205.  
  206. }
  207. void MyInput()
  208. {
  209. movementInput.x = Input.GetAxisRaw("Horizontal");
  210. movementInput.y = Input.GetAxisRaw("Vertical");
  211. isSprinting = Input.GetKey(sprintKey);
  212. /* if (horizontalMovement != 0 || verticalMovement != 0)
  213. {
  214. time += Time.deltaTime;
  215. }
  216. else time = 0; */
  217.  
  218. moveDirection = (orientation.forward * movementInput.y + orientation.right * movementInput.x).normalized;
  219. //Debug.Log(Input.GetAxisRaw("Vertical"));
  220.  
  221. slopeMoveDirection = Vector3.ProjectOnPlane(moveDirection, slopeHit.normal);
  222. }
  223.  
  224. public IEnumerator primeMonkeyBoost()
  225. {
  226. bool doBoost = false;
  227. readyingBoost = true;
  228. yield return 3;
  229.  
  230. float time = 0.2f;
  231.  
  232. while(time > 0)
  233. {
  234. time -= Time.deltaTime;
  235. if(Input.GetKeyDown(jumpKey))
  236. {
  237. doBoost = true;
  238. break;
  239. }
  240.  
  241. yield return null;
  242. }
  243.  
  244. Debug.Log("Boosting: " + doBoost);
  245. if (doBoost) MonkeyBoost();
  246.  
  247. readyingBoost = false;
  248. }
  249. public void MonkeyBoost()
  250. {
  251. onMonkeyBoost?.Invoke();
  252. isMonkeyBoosting = true;
  253. currentCoyoteTime = 0f;
  254. jumpBuffered = false;
  255. rb.velocity = new Vector3(rb.velocity.x, -3f, rb.velocity.z);
  256. rb.AddForce(transform.up * upwardLeapForce, ForceMode.Impulse);
  257. rb.AddForce(moveDirection * forwardLeapForce, ForceMode.Impulse);
  258. StartCoroutine(monkeyBoostTimer());
  259. }
  260.  
  261. IEnumerator monkeyBoostTimer()
  262. {
  263. monkeyBoostAvailable = false;
  264. yield return new WaitForSeconds(monkeyBoostCooldown);
  265. onMonkeyBoostReady?.Invoke();
  266. monkeyBoostAvailable = true;
  267. isMonkeyBoosting = false;
  268. }
  269.  
  270. public void FillMonkeyBoostBar()
  271. {
  272. Debug.Log("OOO OOO AH AH");
  273. StopCoroutine(monkeyBoostTimer());
  274. onMonkeyBoostReady?.Invoke();
  275. monkeyBoostAvailable = true;
  276. isMonkeyBoosting = false;
  277. }
  278. void Jump()
  279. {
  280. currentCoyoteTime = 0f;
  281. jumpBuffered = false;
  282. rb.velocity = new Vector3(rb.velocity.x, -3f, rb.velocity.z);
  283. rb.AddForce(transform.up * currentjumpForce, ForceMode.Impulse);
  284. }
  285.  
  286. IEnumerator JumpBuffer()
  287. {
  288. jumpBuffered = true;
  289. yield return new WaitForSeconds(inputBufferTime);
  290. jumpBuffered = false;
  291. }
  292.  
  293. void ControlSpeed()
  294. {
  295. /* if (crouchRef.isCrouching && isGrounded)
  296. {
  297. moveSpeed = Mathf.Lerp(moveSpeed, currentcrouchSpeed, acceleration * Time.deltaTime);
  298. } */
  299. if (!isGrounded)
  300. {
  301. moveSpeed = Mathf.Lerp(moveSpeed, currentwalkSpeed * 0.7f, 5f * Time.deltaTime);
  302. }
  303. else if (crouchScript.isCrouching)
  304. {
  305. moveSpeed = Mathf.Lerp(moveSpeed, currentcrouchSpeed, acceleration * Time.deltaTime);
  306. }
  307. else if (Input.GetKey(sprintKey) && isGrounded && currentStamina > 0)
  308. {
  309. moveSpeed = Mathf.Lerp(moveSpeed, currentsprintSpeed, acceleration * Time.deltaTime);
  310. currentStamina -= staminaLostRate * Time.fixedDeltaTime;
  311. startStaminaRegain = false;
  312. }
  313. else
  314. {
  315. moveSpeed = Mathf.Lerp(moveSpeed, currentwalkSpeed, acceleration * Time.deltaTime);
  316. // moveSpeed = accelTest.Evaluate(time);
  317. }
  318. }
  319.  
  320. IEnumerator regainStamina()
  321. {
  322. yield return new WaitForSeconds(2f);
  323.  
  324. while(currentStamina < maxStamina)
  325. {
  326. currentStamina += Time.fixedDeltaTime * 7.5f;
  327. if (isSprinting)
  328. {
  329. startStaminaRegain = false;
  330. yield break;
  331. }
  332. yield return null;
  333. }
  334.  
  335. currentStamina = maxStamina;
  336. startStaminaRegain = false;
  337. }
  338.  
  339. void ControlDrag()
  340. {
  341. if (isGrounded)
  342. {
  343. rb.drag = groundDrag;
  344. }
  345. else if (!isMonkeyBoosting)
  346. {
  347. rb.drag = airDrag;
  348. }
  349. else rb.drag = monkeyBoostAirDrag;
  350. }
  351.  
  352. public void ChangeMobility(float amount)
  353. {
  354. currentcrouchSpeed = crouchSpeed * amount;
  355. currentwalkSpeed = walkSpeed * amount;
  356. currentsprintSpeed = sprintSpeed * amount;
  357. currentjumpForce = jumpForce * amount;
  358. }
  359.  
  360. public void ChangeMobility(float amount, bool isInfinite = false, float timeActive = 10f)
  361. {
  362. currentcrouchSpeed = crouchSpeed * amount;
  363. currentwalkSpeed = walkSpeed * amount;
  364. currentsprintSpeed = sprintSpeed * amount;
  365. if (isInfinite == false) Invoke("RevertSpeed", timeActive);
  366. }
  367.  
  368.  
  369. public void RevertSpeed()
  370. {
  371. currentcrouchSpeed = crouchSpeed;
  372. currentwalkSpeed = walkSpeed;
  373. currentsprintSpeed = sprintSpeed;
  374. currentjumpForce = jumpForce;
  375. }
  376.  
  377. void MovePlayer()
  378. {
  379. if (isGrounded && OnSlope())
  380. {
  381. velocityY = 0f;
  382. PreventSlopeSlide();
  383. rb.AddForce(slopeMoveDirection * moveSpeed * slopeSpeedMult * movementMultiplier, ForceMode.Acceleration);
  384. }
  385. else if (isGrounded && !OnSlope())
  386. {
  387. velocityY = 0f;
  388. rb.AddForce(moveDirection * moveSpeed * movementMultiplier, ForceMode.Acceleration);
  389. }
  390. else if (!isGrounded)
  391. {
  392. velocityY += gravity * Time.deltaTime;
  393. rb.AddForce((moveDirection * moveSpeed * movementMultiplier * airMultiplier) + Vector3.up * velocityY, ForceMode.Acceleration);
  394. }
  395.  
  396. // rb.useGravity = !OnSlope();
  397. }
  398.  
  399. void PreventSlopeSlide()
  400. {
  401. if (slopeMoveDirection == Vector3.zero) GetComponent<Collider>().material.dynamicFriction = Mathf.Lerp(GetComponent<Collider>().material.dynamicFriction, 0.8f, 3f * Time.deltaTime);
  402. else GetComponent<Collider>().material.dynamicFriction = 0;
  403. }
  404. private bool OnSlope()
  405. {
  406. if (Physics.Raycast(transform.position, Vector3.down, out slopeHit, 1.25f, groundMask))
  407. {
  408. float slopeAngle = Vector3.Angle(slopeHit.normal, Vector3.up);
  409.  
  410. if(slopeAngle > 0)
  411. {
  412. float angleLerp = Mathf.InverseLerp(35f, 65f, slopeAngle);
  413. slopeSpeedMult = 1.05f;
  414. return true;
  415. }
  416.  
  417. /* if (slopeAngle >= 45f)
  418. {
  419. slopeSpeedMult = 1.35f;
  420. return true;
  421. }
  422. else if (slopeAngle >= 30f)
  423. {
  424. slopeSpeedMult = 1.2f;
  425. return true;
  426. }
  427. else if (slopeAngle >= 15f)
  428. {
  429. slopeSpeedMult = 1.15f;
  430. return true;
  431. } */
  432.  
  433. return false;
  434. }
  435.  
  436. return false;
  437. }
  438.  
  439. private void OnDisable()
  440. {
  441. moveDirection = Vector3.zero;
  442. }
  443.  
  444. private void OnValidate()
  445. {
  446. RevertSpeed();
  447. }
  448.  
  449. private void OnDrawGizmos()
  450. {
  451. if (groundCheck != null) Gizmos.DrawSphere(groundCheck.position, groundDistance);
  452. }
  453.  
  454. public void ResetGravity()
  455. {
  456. velocityY = 0;
  457. }
  458. // WHy does this work? No Idea.
  459. bool MovingTowardsPoint(Vector3 point)
  460. {
  461. Vector3 dirToTarget = Vector3.Normalize(point - transform.position);
  462. float dot = Vector3.Dot(moveDirection, new Vector3(dirToTarget.x, 0, dirToTarget.z));
  463. if (dot >= 0.2f) return true;
  464. else return false;
  465. }
  466. }
Advertisement
Add Comment
Please, Sign In to add comment