140 lines
4.2 KiB
C#
140 lines
4.2 KiB
C#
|
|
using OTGIntegrated.Stats;
|
||
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
namespace OTGIntegrated.Player
|
||
|
|
{
|
||
|
|
[RequireComponent(typeof(CharacterController))]
|
||
|
|
public sealed class PlayerController : MonoBehaviour
|
||
|
|
{
|
||
|
|
[Header("Movement")]
|
||
|
|
[SerializeField] private float rotationSpeed = 12f;
|
||
|
|
[SerializeField] private float gravity = -24f;
|
||
|
|
|
||
|
|
[Header("Camera")]
|
||
|
|
public Transform cameraRoot;
|
||
|
|
public Camera playerCamera;
|
||
|
|
[SerializeField] private Vector3 cameraOffset = new Vector3(0f, 8.5f, -12.5f);
|
||
|
|
[SerializeField] private float mouseSensitivity = 2.2f;
|
||
|
|
|
||
|
|
private CharacterController characterController;
|
||
|
|
private PlayerStats playerStats;
|
||
|
|
private Vector3 velocity;
|
||
|
|
private float cameraYaw;
|
||
|
|
private bool inputEnabled = true;
|
||
|
|
|
||
|
|
public bool InputEnabled => inputEnabled;
|
||
|
|
|
||
|
|
public void Initialize(PlayerStats stats)
|
||
|
|
{
|
||
|
|
playerStats = stats != null ? stats : GetComponent<PlayerStats>();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void Awake()
|
||
|
|
{
|
||
|
|
characterController = GetComponent<CharacterController>();
|
||
|
|
if (playerStats == null)
|
||
|
|
{
|
||
|
|
playerStats = GetComponent<PlayerStats>();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (playerCamera == null)
|
||
|
|
{
|
||
|
|
playerCamera = Camera.main;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (cameraRoot == null)
|
||
|
|
{
|
||
|
|
GameObject root = new GameObject("CameraRoot");
|
||
|
|
cameraRoot = root.transform;
|
||
|
|
cameraRoot.position = transform.position;
|
||
|
|
}
|
||
|
|
|
||
|
|
Cursor.lockState = CursorLockMode.Locked;
|
||
|
|
Cursor.visible = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void Update()
|
||
|
|
{
|
||
|
|
if (!inputEnabled)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
HandleCameraInput();
|
||
|
|
HandleMovement();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void LateUpdate()
|
||
|
|
{
|
||
|
|
UpdateCamera();
|
||
|
|
}
|
||
|
|
|
||
|
|
public void SetInputEnabled(bool enabled)
|
||
|
|
{
|
||
|
|
inputEnabled = enabled;
|
||
|
|
if (!enabled)
|
||
|
|
{
|
||
|
|
velocity.x = 0f;
|
||
|
|
velocity.z = 0f;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public Vector3 GetAimForward()
|
||
|
|
{
|
||
|
|
Vector3 forward = playerCamera != null ? playerCamera.transform.forward : transform.forward;
|
||
|
|
forward.y = 0f;
|
||
|
|
return forward.sqrMagnitude > 0.001f ? forward.normalized : transform.forward;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void HandleCameraInput()
|
||
|
|
{
|
||
|
|
cameraYaw += Input.GetAxis("Mouse X") * mouseSensitivity;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void HandleMovement()
|
||
|
|
{
|
||
|
|
float horizontal = Input.GetAxisRaw("Horizontal");
|
||
|
|
float vertical = Input.GetAxisRaw("Vertical");
|
||
|
|
Vector3 input = new Vector3(horizontal, 0f, vertical);
|
||
|
|
input = Vector3.ClampMagnitude(input, 1f);
|
||
|
|
|
||
|
|
Quaternion yawRotation = Quaternion.Euler(0f, cameraYaw, 0f);
|
||
|
|
Vector3 move = yawRotation * input;
|
||
|
|
float moveSpeed = playerStats != null ? playerStats.MoveSpeed : 5f;
|
||
|
|
|
||
|
|
if (move.sqrMagnitude > 0.001f)
|
||
|
|
{
|
||
|
|
Quaternion targetRotation = Quaternion.LookRotation(move, Vector3.up);
|
||
|
|
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (characterController.isGrounded && velocity.y < 0f)
|
||
|
|
{
|
||
|
|
velocity.y = -2f;
|
||
|
|
}
|
||
|
|
|
||
|
|
velocity.y += gravity * Time.deltaTime;
|
||
|
|
Vector3 motion = move * moveSpeed + Vector3.up * velocity.y;
|
||
|
|
characterController.Move(motion * Time.deltaTime);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void UpdateCamera()
|
||
|
|
{
|
||
|
|
if (cameraRoot == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
cameraRoot.position = transform.position;
|
||
|
|
cameraRoot.rotation = Quaternion.Euler(0f, cameraYaw, 0f);
|
||
|
|
|
||
|
|
if (playerCamera != null)
|
||
|
|
{
|
||
|
|
Vector3 offset = Quaternion.Euler(0f, cameraYaw, 0f) * cameraOffset;
|
||
|
|
playerCamera.transform.position = transform.position + offset;
|
||
|
|
playerCamera.transform.LookAt(transform.position + Vector3.up * 1.1f);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|