using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; public class PlayerMovement : MonoBehaviour { private CharacterController charController; [SerializeField] private Animator _cameraAnimator; public Animator _CharacterAnimator; public float _CurrentSpeed; [SerializeField] private float _WalkSpeed = 2f; //The movement walk speed of the player. [SerializeField] private float _RunSpeed = 3.5f; //The movement run speed of the player. [SerializeField] private float _CrouchSpeed = 1f; private float _WalkSpeedDefaultValue; public float speedSmoothTime = 0.1f; float _SpeedSmoothVelocity; // The original standing height of the Character Controller private float standingHeight; // The crouching height of the Character Controller public float crouchingHeight = 1.2f; // The original position of the model relative to the Character Controller private Vector3 modelOriginalPosition; // The crouching position of the model relative to the Character Controller public Vector3 crouchingModelPosition = new Vector3(0f, 0.148f, 0f); private Vector3[] originalChildPositions; // Store original relative positions of children. public Vector3 crouchingChildOffset = new Vector3(0f, -0.25f, 0f); // Offset to adjust child positions when crouching. public Transform notMovableTransforms; public Vector3 notMovableTransformsOriginalPosition; public Vector3 crouchingNotMovableTransformsOffset = new Vector3(0f, 0.11f, 0f); // Offset to adjust not movable transform position when crouching. [SerializeField] private float JumpHeight = 1.5f; //How much the player can perform a jump. [SerializeField] private float gravity = -9.81f; [SerializeField] private Transform groundCheck; [SerializeField] private float groundDistance = 0.4f; [SerializeField] private LayerMask groundMask; [SerializeField] private bool _isWalking; public bool _isRunning; public bool wasRunning; public event UnityAction OnRunning; public event UnityAction OnStoppedRunning; public Transform cameraBedHidePosition; [SerializeField] private Transform _CameraCrouchPosition; public Vector3 _cameraDefaultPOS; public Quaternion cameraDefaultROT; Vector3 velocity; bool isGrounded; public bool isWalking; [HideInInspector] public bool isMoving; public bool isInAir; public bool canCrouch = true; public bool isCrouching; bool isCrouchingUnderCeiling; public bool CanPressButtonDown = true; public float CrouchLerpTime; [Header("Raycasting")] RaycastHit hit; [SerializeField] private Transform _ceilingRay; [SerializeField] private GameObject _currentHitObject; [SerializeField] private GameObject _previousHitObject; void Awake() { charController = GetComponent(); _WalkSpeedDefaultValue = _WalkSpeed; } // Start is called before the first frame update private void Start() { _cameraDefaultPOS = PlayerManager.GetInstance()._cameraMovement.transform.localPosition; cameraDefaultROT = PlayerManager.GetInstance()._cameraMovement.transform.localRotation; standingHeight = charController.height; modelOriginalPosition = _CharacterAnimator.transform.localPosition; // Assuming the model is the first child of the character. StoreOriginalChildPositions(); StoreNotMovableTransformsOriginalPosition(); } private void StoreOriginalChildPositions() { int childCount = transform.childCount; originalChildPositions = new Vector3[childCount]; for (int i = 0; i < childCount; i++) { originalChildPositions[i] = transform.GetChild(i).localPosition; } } private void AdjustChildrenPositions(Vector3 offset) { int childCount = transform.childCount; for (int i = 0; i < childCount; i++) { Transform child = transform.GetChild(i); child.localPosition = originalChildPositions[i] + offset; } } private void ResetChildrenPositions() { int childCount = transform.childCount; for (int i = 0; i < childCount; i++) { Transform child = transform.GetChild(i); child.localPosition = originalChildPositions[i]; } } private void StoreNotMovableTransformsOriginalPosition() { notMovableTransformsOriginalPosition = notMovableTransforms.localPosition; } private void AdjustNotMovableTransformsPosition(Vector3 offset) { notMovableTransforms.localPosition = notMovableTransformsOriginalPosition + offset; } private void ResetNotMovableTransformsPosition() { notMovableTransforms.localPosition = notMovableTransformsOriginalPosition; } // Update is called once per frame void Update() { isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask); //Checks if the player is grounded. if(isGrounded && velocity.y < 0) { velocity.y = -2f; isInAir = false; } else { isInAir = true; } float horizontal = Input.GetAxis("Horizontal"); float vertical = Input.GetAxis("Vertical"); Vector3 move; float joystickHorizontal = Input.GetAxis("Joystick Horizontal"); float joystickVertical = Input.GetAxis("Joystick Vertical"); float mag; if (InputControlManager.Getinstance().IsUsingJoystick == false) { mag = Mathf.Clamp01(new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")).magnitude); //This is when the player moves diagonaly move = (transform.right * horizontal + transform.forward * vertical).normalized; } else { mag = Mathf.Clamp01(new Vector2(Input.GetAxis("Joystick Horizontal"), Input.GetAxis("Joystick Vertical")).magnitude); //This is when the player moves diagonaly move = (transform.right * joystickHorizontal + transform.forward * joystickVertical).normalized; } charController.Move(move * _CurrentSpeed * Time.deltaTime); //Moves the character around. //Walking : if (vertical != 0 || horizontal != 0 || joystickVertical != 0 || joystickHorizontal != 0 || mag != 0 || -mag != 0 && isGrounded) { // _cameraAnimator.SetBool(("IsMoving"), true); isMoving = true; if(_isRunning == false) { isWalking = true; } } else { // _cameraAnimator.SetBool(("IsMoving"), false); isMoving = false; isWalking = false; } //Makes the player speed up . if (Input.GetKey(KeyCode.LeftShift) && isMoving && !isCrouching || Input.GetKey(KeyCode.JoystickButton5) && isMoving && !isCrouching) { _CurrentSpeed = _RunSpeed; _isRunning = true; //print("Player is sprinting"); } else if (!isCrouching) { _isRunning = false; _CurrentSpeed = _WalkSpeed; } if (_isRunning && !wasRunning) { OnRunning?.Invoke(); wasRunning = true; } else if (!_isRunning && wasRunning) { OnStoppedRunning?.Invoke(); wasRunning = false; } //if(Input.GetButtonDown("Jump") && isGrounded && !isCrouching) //Player can perform a jump if he's in the ground. //{ // velocity.y = Mathf.Sqrt(JumpHeight * -2f * gravity); //} velocity.y += gravity * Time.deltaTime; charController.Move(velocity * Time.deltaTime); float targetSpeed = ((_isRunning) ? _RunSpeed : _WalkSpeed) * move.magnitude; _CurrentSpeed = Mathf.SmoothDamp(_CurrentSpeed, targetSpeed, ref _SpeedSmoothVelocity, speedSmoothTime); float animationSpeedPercent = ((_isRunning) ? 1 : .5f) * move.magnitude; _CharacterAnimator.SetFloat("speedPercent", animationSpeedPercent, speedSmoothTime, Time.deltaTime); #region Crouch if (UIManager.GetInstance().userInterfaceIsOnScreen == false) { if (Input.GetKeyDown(KeyCode.LeftControl) && !isCrouching && !isInAir && CanPressButtonDown || Input.GetKeyDown(KeyCode.JoystickButton1) && !isCrouching && !isInAir && CanPressButtonDown) { if (canCrouch) { #region NEW BULSHIT! StopAllCoroutines(); StartCoroutine(CrouchDown()); //AdjustChildrenPositions(crouchingChildOffset); #endregion //charController.height = 0.8f; //charController.stepOffset = 0.2f; // Crouch charController.height = crouchingHeight; charController.center = new Vector3(0, 0.7f, 0.1f); _CharacterAnimator.transform.localPosition = crouchingModelPosition; AdjustNotMovableTransformsPosition(crouchingNotMovableTransformsOffset); isCrouching = true; StartCoroutine(PressButtonDelay()); _CharacterAnimator.SetBool("IsCrouching", true); CrouchLerpTime = 0.0f; //Sets lerp time back to normal. //CameraMovement.GetInstance().transform.position = Vector3.Lerp(CameraMovement.GetInstance().transform.position , _CameraCrouchPosition.position, CrouchLerpTime * Time.deltaTime); } } else if (Input.GetKeyDown(KeyCode.LeftControl) && isCrouching && CanPressButtonDown || Input.GetKeyDown(KeyCode.JoystickButton1) && isCrouching && CanPressButtonDown) { #region NEW BULSHIT! StopAllCoroutines(); CrouchLerpTime = 0.0f; //Sets lerp time back to normal. #endregion StartCoroutine(CrouchStandUp()); //ResetChildrenPositions(); //charController.stepOffset = 0.4f; // Stand up charController.height = standingHeight; charController.center = new Vector3(0, 0.7f, 0f); _CharacterAnimator.transform.localPosition = modelOriginalPosition; ResetNotMovableTransformsPosition(); StartCoroutine(PressButtonDelay()); isCrouching = false; _CharacterAnimator.SetBool("IsCrouching", false); } } if (isCrouching) //If player is crouching: { Ray ray = new Ray(_ceilingRay.position, Vector3.up); float rayDistance = 0.2f; Debug.DrawRay(_ceilingRay.position, Vector3.up * rayDistance, Color.blue); if (Physics.Raycast(ray, out hit, rayDistance)) { _currentHitObject = hit.transform.gameObject; if (hit.collider) { CanPressButtonDown = false; isCrouchingUnderCeiling = true; Debug.Log(_previousHitObject, _currentHitObject); } } else { if (isCrouchingUnderCeiling) { CanPressButtonDown = true; isCrouchingUnderCeiling = false; } } _CurrentSpeed = _CrouchSpeed; } #endregion } IEnumerator CrouchDown() { //yield return new WaitForSeconds(0.1f); //while (CrouchLerpTime <= 1f) //{ // //charController.height = Mathf.Lerp(charController.height, 0.8f, CrouchLerpTime); // PlayerManager.GetInstance().PlayerMainCamera.transform.localPosition = Vector3.Lerp(PlayerManager.GetInstance()._cameraMovement.transform.localPosition, _CameraCrouchPosition.localPosition, CrouchLerpTime); // //Mathf.Round((charController.height * 10) / 10); // CrouchLerpTime += 1.7f * Time.deltaTime; // yield return null; //} Vector3 initialPosition = transform.localPosition; Vector3 targetPosition = _CameraCrouchPosition.localPosition; float distance = Vector3.Distance(initialPosition, targetPosition); while (distance > 0.01f) // Use a small threshold to determine when to stop lerping. { // Lerp the camera's position from initialPosition to targetPosition. PlayerManager.GetInstance()._cameraMovement.transform.localPosition = Vector3.Lerp(PlayerManager.GetInstance()._cameraMovement.transform.localPosition, targetPosition, 8f * Time.deltaTime); distance = Vector3.Distance(PlayerManager.GetInstance()._cameraMovement.transform.localPosition, targetPosition); yield return null; } // Ensure the camera reaches exactly the target position to avoid precision errors. PlayerManager.GetInstance()._cameraMovement.transform.localPosition = targetPosition; } IEnumerator CrouchStandUp() { //while (CrouchLerpTime <= 1f) //{ // //charController.height = Mathf.Lerp(charController.height, 1.40f, CrouchLerpTime); // PlayerManager.GetInstance().PlayerMainCamera.transform.localPosition = Vector3.Lerp(PlayerManager.GetInstance()._cameraMovement.transform.localPosition, _cameraDefaultPOS, CrouchLerpTime); // //Mathf.Round((charController.height * 10) / 10); // CrouchLerpTime += 1.7f * Time.deltaTime; // yield return null; //} Vector3 initialPosition = transform.localPosition; Vector3 targetPosition = _cameraDefaultPOS; float distance = Vector3.Distance(initialPosition, _cameraDefaultPOS); while (distance > 0.01f) // Use a small threshold to determine when to stop lerping. { // Lerp the camera's position from initialPosition to targetPosition. PlayerManager.GetInstance()._cameraMovement.transform.localPosition = Vector3.Lerp(PlayerManager.GetInstance()._cameraMovement.transform.localPosition, targetPosition, 6f * Time.deltaTime); distance = Vector3.Distance(PlayerManager.GetInstance()._cameraMovement.transform.localPosition, targetPosition); yield return null; } // Ensure the camera reaches exactly the target position to avoid precision errors. PlayerManager.GetInstance()._cameraMovement.transform.localPosition = targetPosition; } public void ForcePlayerStandUpFromCrouch() { Vector3 targetPosition = _cameraDefaultPOS; PlayerManager.GetInstance()._cameraMovement.transform.localPosition = targetPosition; charController.height = standingHeight; _CharacterAnimator.transform.localPosition = modelOriginalPosition; ResetNotMovableTransformsPosition(); isCrouching = false; _CharacterAnimator.SetBool("IsCrouching", false); } IEnumerator PressButtonDelay() { CanPressButtonDown = false; yield return new WaitForSeconds(0.2f); CanPressButtonDown = true; } }