403 lines
15 KiB
C#
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;
|
|
}
|
|
|
|
}
|