Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using UnityEngine;
- using TMPro;
- public class PlayerController : MonoBehaviour
- {
- public bool CanMove { get; private set; } = true;
- private bool isSprinting => canSprint && Input.GetKey(sprintKey) && !isCrouching;
- private bool shouldJump => Input.GetKeyDown(jumpKey) && characterController.isGrounded && !isCrouching;
- private bool shouldCrouch => Input.GetKeyDown(crouchKey) && characterController.isGrounded;
- [Header("Functional Options")]
- [SerializeField] private bool canSprint = true;
- [SerializeField] private bool canJump = true;
- [SerializeField] private bool canCrouch = true;
- [SerializeField] private bool canUseStamina = true;
- [SerializeField] private bool canUseHeadbob = true;
- [SerializeField] private bool canUseSlopes = true;
- [SerializeField] private bool canZoom = true;
- [SerializeField] private bool canUseFootsteps = true;
- [SerializeField] private bool canInteract = true;
- [SerializeField] private bool canUseAnimation = true;
- [SerializeField] private bool canUseFlashlight = true;
- [Header("Controls")]
- [SerializeField] private KeyCode sprintKey = KeyCode.LeftShift;
- [SerializeField] private KeyCode jumpKey = KeyCode.Space;
- [SerializeField] private KeyCode crouchKey = KeyCode.LeftControl;
- [SerializeField] private KeyCode zoomKey = KeyCode.Mouse2;
- [SerializeField] private KeyCode interactKey = KeyCode.Mouse0;
- [SerializeField] private KeyCode flashlightKey = KeyCode.E;
- [Header("Movement Parameters")]
- [SerializeField] private float walkSpeed = 3.0f;
- [SerializeField] private float sprintSpeed = 6.0f;
- [SerializeField] private float crouchSpeed = 1.5f;
- [SerializeField] private float slopeSpeed = 8f;
- [Header("Look Parameters")]
- [SerializeField, Range(1, 10)] private float lookSpeedX = 2.0f;
- [SerializeField, Range(1, 10)] private float lookSpeedY = 2.0f;
- [SerializeField, Range(1, 180)] private float upperLookLimit = 80f;
- [SerializeField, Range(1, 180)] private float lowerLookLimit = 80f;
- [Header("Jumping Parameters")]
- [SerializeField] private float jumpForce = 8.0f;
- [SerializeField] private float gravity = 30.0f;
- [Header("Crouch Parameters")]
- [SerializeField] private float crouchHeight = 0.5f;
- [SerializeField] private float standingHeight = 2f;
- [SerializeField] private float timeToCrouch = 0.25f;
- [SerializeField] private Vector3 crouchingCenter = new Vector3(0, 0.5f, 0);
- [SerializeField] private Vector3 standingCenter = new Vector3(0, 0, 0);
- private bool isCrouching = false;
- private bool duringCrouchAnimation = false;
- [Header("Stamina Parameters")]
- [SerializeField] private float maxStamina = 100f;
- [SerializeField] private float staminaUseMultiplier = 5f;
- [SerializeField] private float timeBeforeStaminaRegenStarts = 5f;
- [SerializeField] private float staminaValueIncrement = 2f;
- [SerializeField] private float staminaTimeIncrement = 0.1f;
- public float currentStamina;
- private Coroutine regeneratingStamina;
- public static Action<float> OnStaminaChange;
- [Header("Headbob Parameters")]
- [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;
- [Header("Slope Parameters")]
- [SerializeField] private float slopeForce;
- [SerializeField] private float slopeForceRayLength;
- private RaycastHit slopeSlideHit;
- private RaycastHit slopeWalkHit;
- private bool isSlopeSliding
- {
- get
- {
- if (characterController.isGrounded && Physics.Raycast(transform.position, Vector3.down, out slopeSlideHit, slopeForceRayLength))
- {
- return Vector3.Angle(slopeSlideHit.normal, Vector3.up) > characterController.slopeLimit;
- }
- else
- {
- return false;
- }
- }
- }
- private bool isSlopeWalking()
- {
- if (Physics.Raycast(transform.position, Vector3.down, out slopeWalkHit, characterController.height / 2 + slopeForceRayLength))
- {
- return (slopeWalkHit.normal != Vector3.up) && (Vector3.Angle(slopeWalkHit.normal, Vector3.up) < characterController.slopeLimit);
- }
- else
- {
- return false;
- }
- }
- [Header("Zoom Parameters")]
- [SerializeField] private float timeToZoom = 0.3f;
- [SerializeField] private float zoomFOV = 45f;
- private float defaultFOV;
- private Coroutine zoomRoutine;
- [Header("Footsteps Parameters")]
- [SerializeField] private float baseStepSpeed = 0.5f;
- [SerializeField] private float crouchStepMultiplier = 1.5f;
- [SerializeField] private float sprintStepMultiplier = 0.6f;
- [SerializeField] private AudioSource footstepAudioSource = default;
- [SerializeField] private AudioClip[] stoneClips = default;
- [SerializeField] private AudioClip[] metalClips = default;
- private float footstepTimer = 0f;
- private float GetCurrentOffset => isCrouching ? baseStepSpeed * crouchStepMultiplier : isSprinting ? baseStepSpeed * sprintStepMultiplier : baseStepSpeed;
- [Header("Interaction")]
- [SerializeField] private Vector3 interactionRayPoint = default;
- [SerializeField] private float interactionDistance = default;
- [SerializeField] private LayerMask interactionLayer = default;
- public GameObject interactOB;
- public bool shouldRemoveText = true;
- public TextMeshProUGUI textDisplay;
- private Interactable currentInteractable;
- [Header("Flashlight")]
- [SerializeField] private GameObject flashlight;
- [SerializeField] public bool isEquip;
- [SerializeField] private float delayTime;
- [SerializeField] private AudioSource flashlightAudioSource = default;
- [SerializeField] private AudioClip flashlightOnOff;
- [Header("SFX")]
- [SerializeField] private AudioSource heartBeat;
- [SerializeField] private AudioSource pickUp;
- private Camera playerCamera;
- private CharacterController characterController;
- private Vector3 moveDirection;
- private Vector2 currentInput;
- private bool isMoving = false;
- private float rotationX = 0f;
- public static PlayerController instance;
- public bool canUseMovement = true;
- public bool canUseMouse = true;
- void Awake()
- {
- instance = this;
- interactOB.SetActive(false);
- isEquip = false;
- flashlight.SetActive(false);
- playerCamera = GetComponentInChildren<Camera>();
- characterController = GetComponent<CharacterController>();
- defaultYPos = playerCamera.transform.localPosition.y;
- defaultFOV = playerCamera.fieldOfView;
- currentStamina = maxStamina;
- StartCoroutine(CrouchStand());
- Cursor.lockState = CursorLockMode.Locked;
- Cursor.visible = false;
- }
- void Update()
- {
- if (CanMove)
- {
- if (canUseMovement)
- {
- HandleMovementInput();
- }
- else
- {
- currentInput = Vector2.zero;
- moveDirection = Vector3.zero;
- }
- if (canUseMouse)
- {
- HandleMouseLook();
- }
- isMoving = Mathf.Abs(moveDirection.x) < 0.01f || Mathf.Abs(moveDirection.z) < 0.02f ? false : true;
- if (canJump)
- {
- HandleJump();
- }
- if (canCrouch)
- {
- HandleCrouch();
- }
- if (canUseStamina)
- {
- HandleStamina();
- }
- if (canUseHeadbob)
- {
- HandleHeadbob();
- }
- if (canUseSlopes)
- {
- HandleSlopes();
- }
- if (canZoom)
- {
- HandleZoom();
- }
- if (canUseFootsteps)
- {
- HandleFootsteps();
- }
- if (canInteract)
- {
- HandleInteractionCheck();
- HandleInteractionInput();
- }
- if (canUseFlashlight)
- {
- HandleFlashlight();
- }
- ApplyFinalMovements();
- }
- }
- private void HandleMovementInput()
- {
- currentInput = new Vector2((isCrouching ? crouchSpeed : isSprinting ? sprintSpeed : walkSpeed) * Input.GetAxis("Vertical"), (isCrouching ? crouchSpeed : isSprinting ? sprintSpeed : walkSpeed) * Input.GetAxis("Horizontal"));
- float moveDirectionY = moveDirection.y;
- moveDirection = (transform.TransformDirection(Vector3.forward) * currentInput.x) + (transform.TransformDirection(Vector3.right) * currentInput.y);
- moveDirection.y = moveDirectionY;
- }
- private void HandleMouseLook()
- {
- rotationX -= Input.GetAxis("Mouse Y") * GetSettings.instance.mouseSens;
- rotationX = Mathf.Clamp(rotationX, -upperLookLimit, lowerLookLimit);
- playerCamera.transform.localRotation = Quaternion.Euler(rotationX, 0, 0);
- transform.rotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * GetSettings.instance.mouseSens, 0);
- }
- private void HandleJump()
- {
- if (shouldJump)
- {
- moveDirection.y = jumpForce;
- }
- }
- private void HandleCrouch()
- {
- if (shouldCrouch)
- {
- StartCoroutine(CrouchStand());
- }
- }
- private IEnumerator CrouchStand()
- {
- if (isCrouching && Physics.Raycast(playerCamera.transform.position, Vector3.up, 2f))
- {
- yield break;
- }
- duringCrouchAnimation = !duringCrouchAnimation;
- float timeElapsed = 0f;
- float targetHeight = isCrouching ? standingHeight : crouchHeight;
- float currentHeight = characterController.height;
- Vector3 targetCenter = isCrouching ? standingCenter : crouchingCenter;
- Vector3 currentCenter = characterController.center;
- while (timeElapsed < timeToCrouch)
- {
- characterController.height = Mathf.Lerp(currentHeight, targetHeight, timeElapsed / timeToCrouch);
- characterController.center = Vector3.Lerp(currentCenter, targetCenter, timeElapsed / timeToCrouch);
- timeElapsed += Time.deltaTime;
- yield return null;
- }
- characterController.height = targetHeight;
- characterController.center = targetCenter;
- isCrouching = !isCrouching;
- }
- private void HandleStamina()
- {
- if (isSprinting && currentInput != Vector2.zero)
- {
- if (regeneratingStamina != null)
- {
- StopCoroutine(regeneratingStamina);
- regeneratingStamina = null;
- }
- currentStamina -= staminaUseMultiplier * Time.deltaTime;
- if (currentStamina < 0f)
- {
- currentStamina = 0f;
- }
- OnStaminaChange?.Invoke(currentStamina);
- if (currentStamina <= 0)
- {
- canSprint = false;
- }
- }
- if (!isSprinting && currentStamina < maxStamina && regeneratingStamina == null)
- {
- regeneratingStamina = StartCoroutine(RegenerateStamina());
- }
- }
- private IEnumerator RegenerateStamina()
- {
- yield return new WaitForSeconds(timeBeforeStaminaRegenStarts);
- WaitForSeconds timeToWait = new WaitForSeconds(staminaTimeIncrement);
- while (currentStamina < maxStamina)
- {
- if (currentStamina > 0f)
- {
- canSprint = true;
- }
- currentStamina += staminaValueIncrement;
- if (currentStamina > maxStamina)
- {
- currentStamina = maxStamina;
- }
- OnStaminaChange?.Invoke(currentStamina);
- yield return timeToWait;
- }
- regeneratingStamina = null;
- }
- private void HandleHeadbob()
- {
- if (!characterController.isGrounded) return;
- if (Mathf.Abs(moveDirection.x) > 0.1f || Mathf.Abs(moveDirection.z) > 0.1f)
- {
- timer += Time.deltaTime * (isCrouching ? crouchBobSpeed : isSprinting ? sprintBobSpeed : walkBobSpeed);
- playerCamera.transform.localPosition = new Vector3(
- playerCamera.transform.localPosition.x,
- defaultYPos + Mathf.Sin(timer) * (isCrouching ? crouchBobAmount : isSprinting ? sprintBobAmount : walkBobAmount),
- playerCamera.transform.localPosition.z);
- }
- }
- private void HandleSlopes()
- {
- if (isSlopeSliding)
- {
- moveDirection += new Vector3(slopeSlideHit.normal.x, -slopeSlideHit.normal.y, slopeSlideHit.normal.z) * slopeSpeed;
- }
- if (isSlopeWalking())
- {
- characterController.Move(Vector3.down * characterController.height / 2 * slopeForce * Time.deltaTime);
- }
- }
- private void HandleZoom()
- {
- if (Input.GetKeyDown(zoomKey))
- {
- if (zoomRoutine != null)
- {
- StopCoroutine(zoomRoutine);
- zoomRoutine = null;
- }
- zoomRoutine = StartCoroutine(ToggleZoom(true));
- }
- if (Input.GetKeyUp(zoomKey))
- {
- if (zoomRoutine != null)
- {
- StopCoroutine(zoomRoutine);
- zoomRoutine = null;
- }
- zoomRoutine = StartCoroutine(ToggleZoom(false));
- }
- }
- private IEnumerator ToggleZoom(bool isEnter)
- {
- float targetFOV = isEnter ? zoomFOV : defaultFOV;
- float startingFOV = playerCamera.fieldOfView;
- float timeElapsed = 0f;
- while (timeElapsed < timeToZoom)
- {
- playerCamera.fieldOfView = Mathf.Lerp(startingFOV, targetFOV, timeElapsed / timeToZoom);
- timeElapsed += Time.deltaTime;
- yield return null;
- }
- playerCamera.fieldOfView = targetFOV;
- zoomRoutine = null;
- }
- private void HandleFootsteps()
- {
- if (currentInput == Vector2.zero) return;
- footstepTimer -= Time.deltaTime;
- if (footstepTimer <= 0)
- {
- if (Physics.Raycast(playerCamera.transform.position, Vector3.down, out RaycastHit hit, 4f))
- {
- switch (hit.collider.tag)
- {
- case "Footsteps/Stone":
- footstepAudioSource.PlayOneShot(stoneClips[UnityEngine.Random.Range(0, stoneClips.Length - 1)]);
- break;
- case "Footsteps/Metal":
- footstepAudioSource.PlayOneShot(metalClips[UnityEngine.Random.Range(0, stoneClips.Length - 1)]);
- break;
- default:
- footstepAudioSource.PlayOneShot(stoneClips[UnityEngine.Random.Range(0, stoneClips.Length - 1)]);
- break;
- }
- }
- footstepTimer = GetCurrentOffset;
- }
- }
- private void HandleInteractionCheck()
- {
- if (Physics.Raycast(playerCamera.ViewportPointToRay(interactionRayPoint), out RaycastHit hit, interactionDistance))
- {
- if (hit.collider.gameObject.layer == 6 && (currentInteractable == null || hit.collider.gameObject.GetInstanceID() != currentInteractable.GetInstanceID()))
- {
- hit.collider.TryGetComponent(out currentInteractable);
- if (currentInteractable)
- {
- currentInteractable.OnFocus();
- }
- }
- }
- else if (currentInteractable)
- {
- currentInteractable.OnLoseFocus();
- currentInteractable = null;
- }
- if (currentInteractable == null)
- {
- if(shouldRemoveText)
- {
- textDisplay.text = "";
- }
- if(shouldRemoveText == false)
- {
- canInteract = false;
- }
- interactOB.SetActive(false);
- }
- }
- private void HandleInteractionInput()
- {
- if (Input.GetKeyDown(interactKey) && currentInteractable != null && Physics.Raycast(playerCamera.ViewportPointToRay(interactionRayPoint), out RaycastHit hit, interactionDistance, interactionLayer))
- {
- currentInteractable.OnInteract();
- }
- }
- //private void HandleAnimation()
- //{
- // if (isEquip)
- // {
- // animator.SetBool("isEquip", true);
- // lantern.SetBool("isEquip", true);
- // if (lanternLightOff)
- // {
- // lanternMat.DisableKeyword("_EMISSION");
- // lantern.SetBool("isLightOff", true);
- // isEquip = true;
- // }
- // else
- // {
- // lanternMat.EnableKeyword("_EMISSION");
- // lantern.SetBool("isLightOff", false);
- // }
- // }
- // else
- // {
- // animator.SetBool("isEquip", false);
- // lantern.SetBool("isEquip", false);
- // }
- // if (!isMoving && isEquip)
- // {
- // animator.SetFloat("speedEquip", 0f, dampTime, Time.deltaTime);
- // }
- // else if (isMoving && isEquip && !isSprinting)
- // {
- // animator.SetFloat("speedEquip", 0.5f, dampTime, Time.deltaTime);
- // }
- // else if (isMoving && isEquip && isSprinting)
- // {
- // animator.SetFloat("speedEquip", 1f, dampTime, Time.deltaTime);
- // }
- // if (!isMoving && !isEquip)
- // {
- // animator.SetFloat("speedDown", 0f, dampTime, Time.deltaTime);
- // }
- // else if (isMoving && !isEquip)
- // {
- // animator.SetFloat("speedDown", 0.5f, dampTime, Time.deltaTime);
- // }
- // if (duringCrouchAnimation)
- // {
- // animator.SetBool("isCrouch", true);
- // }
- // else
- // {
- // animator.SetBool("isCrouch", false);
- // }
- //}
- private void HandleFlashlight()
- {
- if (Input.GetKeyDown(flashlightKey))
- {
- StartCoroutine(UseFlashlight());
- }
- }
- public IEnumerator UseFlashlight()
- {
- isEquip = !isEquip;
- flashlightAudioSource.PlayOneShot(flashlightOnOff);
- canUseFlashlight = false;
- if (isEquip)
- {
- flashlight.SetActive(true);
- }
- if(!isEquip)
- {
- flashlight.SetActive(false);
- }
- yield return new WaitForSeconds(delayTime);
- canUseFlashlight = true;
- }
- //public IEnumerator flashlightSwitch(float timeBetweenSwitch)
- //{
- // lanternLightOff = true;
- // yield return new WaitForSeconds(timeBetweenSwitch);
- // lanternLightOff = false;
- //}
- private void ApplyFinalMovements()
- {
- if (!characterController.isGrounded)
- {
- moveDirection.y -= gravity * Time.deltaTime;
- }
- characterController.Move(moveDirection * Time.deltaTime);
- if (characterController.velocity.y < -1 && characterController.isGrounded)
- {
- moveDirection.y = 0;
- }
- }
- public void heartBeatUp(float timeToChange, float highValue, float timeToGoBack)
- {
- StartCoroutine(higherHeartBeat(timeToChange, highValue, timeToGoBack));
- }
- public void pickUpSFX()
- {
- pickUp.Play();
- }
- IEnumerator higherHeartBeat(float timeToChange, float highValue, float timeToGoBack)
- {
- float timeElapsed = 0f;
- float startingVolume = heartBeat.volume;
- while (timeElapsed < timeToChange)
- {
- heartBeat.volume = Mathf.Lerp(startingVolume, highValue, timeElapsed / timeToChange);
- timeElapsed += Time.deltaTime;
- yield return null;
- }
- heartBeat.volume = highValue;
- yield return new WaitForSeconds(timeToGoBack);
- timeElapsed = 0f;
- startingVolume = heartBeat.volume;
- while (timeElapsed < timeToChange)
- {
- heartBeat.volume = Mathf.Lerp(startingVolume, 0f, timeElapsed / timeToChange);
- timeElapsed += Time.deltaTime;
- yield return null;
- }
- heartBeat.volume = 0f;
- }
- public void EnableFlashlightUse()
- {
- canUseFlashlight = true;
- }
- public void DisableFlashlightUse()
- {
- canUseFlashlight = false;
- }
- public void EnableCrouchUse()
- {
- canCrouch = true;
- }
- public void EnableZoomUse()
- {
- canZoom = true;
- }
- public void EnableInteractUse()
- {
- canInteract = true;
- }
- public void EnableSprintUse()
- {
- canSprint = true;
- }
- public void LockPlayer()
- {
- canUseMouse = false;
- canUseMovement = false;
- }
- public void UnlockPlayer()
- {
- canUseMouse = true;
- canUseMovement = true;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement