Files
HauntedBloodlines/Assets/Scripts/Player/PlayerMovement.cs
2025-05-29 22:31:40 +03:00

403 lines
15 KiB
C#

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<CharacterController>();
_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;
}
}