136 lines
4.0 KiB
C#
136 lines
4.0 KiB
C#
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
[RequireComponent(typeof(CharacterController))]
|
||
|
|
public class SimplePlayerController : MonoBehaviour
|
||
|
|
{
|
||
|
|
[Header("Movement")]
|
||
|
|
public float moveSpeed = 5.5f;
|
||
|
|
public float sprintSpeed = 7.5f;
|
||
|
|
public float jumpHeight = 1.4f;
|
||
|
|
public float gravity = -22f;
|
||
|
|
public float rotationSmoothTime = 0.08f;
|
||
|
|
|
||
|
|
[Header("Camera")]
|
||
|
|
public Transform cameraPivot;
|
||
|
|
public Camera playerCamera;
|
||
|
|
public float cameraDistance = 5.5f;
|
||
|
|
public float mouseSensitivity = 2.2f;
|
||
|
|
public float minPitch = -25f;
|
||
|
|
public float maxPitch = 65f;
|
||
|
|
|
||
|
|
private CharacterController controller;
|
||
|
|
private float verticalVelocity;
|
||
|
|
private float yaw;
|
||
|
|
private float pitch = 20f;
|
||
|
|
private float rotationVelocity;
|
||
|
|
|
||
|
|
private void Awake()
|
||
|
|
{
|
||
|
|
controller = GetComponent<CharacterController>();
|
||
|
|
|
||
|
|
if (cameraPivot == null)
|
||
|
|
{
|
||
|
|
GameObject pivot = new GameObject("Camera Pivot");
|
||
|
|
pivot.transform.SetParent(transform);
|
||
|
|
pivot.transform.localPosition = new Vector3(0f, 1.45f, 0f);
|
||
|
|
cameraPivot = pivot.transform;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (playerCamera == null)
|
||
|
|
{
|
||
|
|
playerCamera = Camera.main;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (playerCamera != null)
|
||
|
|
{
|
||
|
|
playerCamera.transform.SetParent(null);
|
||
|
|
}
|
||
|
|
|
||
|
|
yaw = transform.eulerAngles.y;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void Start()
|
||
|
|
{
|
||
|
|
Cursor.lockState = CursorLockMode.Locked;
|
||
|
|
Cursor.visible = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void Update()
|
||
|
|
{
|
||
|
|
bool uiBlocksMovement =
|
||
|
|
DialogueUI.Instance != null && DialogueUI.Instance.IsOpen ||
|
||
|
|
QuestLogUI.Instance != null && QuestLogUI.Instance.IsOpen;
|
||
|
|
|
||
|
|
if (uiBlocksMovement)
|
||
|
|
{
|
||
|
|
ApplyCamera();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
HandleLook();
|
||
|
|
HandleMovement();
|
||
|
|
ApplyCamera();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void HandleLook()
|
||
|
|
{
|
||
|
|
yaw += Input.GetAxis("Mouse X") * mouseSensitivity;
|
||
|
|
pitch -= Input.GetAxis("Mouse Y") * mouseSensitivity;
|
||
|
|
pitch = Mathf.Clamp(pitch, minPitch, maxPitch);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void HandleMovement()
|
||
|
|
{
|
||
|
|
bool grounded = controller.isGrounded;
|
||
|
|
if (grounded && verticalVelocity < 0f)
|
||
|
|
{
|
||
|
|
verticalVelocity = -2f;
|
||
|
|
}
|
||
|
|
|
||
|
|
Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
|
||
|
|
input = Vector2.ClampMagnitude(input, 1f);
|
||
|
|
|
||
|
|
Vector3 cameraForward = Quaternion.Euler(0f, yaw, 0f) * Vector3.forward;
|
||
|
|
Vector3 cameraRight = Quaternion.Euler(0f, yaw, 0f) * Vector3.right;
|
||
|
|
Vector3 move = cameraForward * input.y + cameraRight * input.x;
|
||
|
|
|
||
|
|
if (move.sqrMagnitude > 0.001f)
|
||
|
|
{
|
||
|
|
float targetAngle = Mathf.Atan2(move.x, move.z) * Mathf.Rad2Deg;
|
||
|
|
float smoothAngle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref rotationVelocity, rotationSmoothTime);
|
||
|
|
transform.rotation = Quaternion.Euler(0f, smoothAngle, 0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (Input.GetButtonDown("Jump") && grounded)
|
||
|
|
{
|
||
|
|
verticalVelocity = Mathf.Sqrt(jumpHeight * -2f * gravity);
|
||
|
|
}
|
||
|
|
|
||
|
|
verticalVelocity += gravity * Time.deltaTime;
|
||
|
|
float speed = Input.GetKey(KeyCode.LeftShift) ? sprintSpeed : moveSpeed;
|
||
|
|
Vector3 velocity = move * speed + Vector3.up * verticalVelocity;
|
||
|
|
controller.Move(velocity * Time.deltaTime);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void ApplyCamera()
|
||
|
|
{
|
||
|
|
if (playerCamera == null || cameraPivot == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
Quaternion rotation = Quaternion.Euler(pitch, yaw, 0f);
|
||
|
|
Vector3 pivot = cameraPivot.position;
|
||
|
|
Vector3 desiredPosition = pivot - rotation * Vector3.forward * cameraDistance;
|
||
|
|
|
||
|
|
if (Physics.Linecast(pivot, desiredPosition, out RaycastHit hit, ~0, QueryTriggerInteraction.Ignore)
|
||
|
|
&& !hit.transform.IsChildOf(transform))
|
||
|
|
{
|
||
|
|
desiredPosition = hit.point + hit.normal * 0.25f;
|
||
|
|
}
|
||
|
|
|
||
|
|
playerCamera.transform.position = desiredPosition;
|
||
|
|
playerCamera.transform.rotation = rotation;
|
||
|
|
}
|
||
|
|
}
|