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