using UnityEngine;
///
/// ควบคุมตัวละคร: เดินตามทิศทางกล้อง (WASD) และหันหน้าไปทางที่เดิน
/// ใส่สคริปต์นี้ที่ตัว Player (ต้องมี CharacterController)
///
[RequireComponent(typeof(CharacterController))]
public class PlayerController : MonoBehaviour
{
[Header("Camera")]
[Tooltip("เว้นว่างไว้ = ใช้ Main Camera")]
[SerializeField] private Transform cameraTransform;
[Header("Movement")]
[SerializeField] private float walkSpeed = 4f;
[SerializeField] private float sprintSpeed = 7f;
[Tooltip("ยิ่งมากยิ่งหันตัวเร็ว")]
[SerializeField] private float turnSpeed = 12f;
[Header("Jump / Gravity")]
[SerializeField] private float jumpHeight = 1.2f;
[SerializeField] private float gravity = -20f;
[Header("Animator (ไม่บังคับ)")]
[SerializeField] private Animator animator;
[SerializeField] private string speedParameter = "Speed";
private CharacterController controller;
private float verticalVelocity;
private int speedHash;
private bool hasSpeedParam;
private void Awake()
{
controller = GetComponent();
if (cameraTransform == null && Camera.main != null)
cameraTransform = Camera.main.transform;
if (animator != null)
{
speedHash = Animator.StringToHash(speedParameter);
foreach (var p in animator.parameters)
if (p.nameHash == speedHash) { hasSpeedParam = true; break; }
}
}
private void Update()
{
if (cameraTransform == null) return;
// ----- ทิศทางเดินอิงตามกล้อง -----
Vector2 input = GameInput.Move;
Vector3 camForward = cameraTransform.forward;
camForward.y = 0f;
camForward.Normalize();
Vector3 camRight = cameraTransform.right;
camRight.y = 0f;
camRight.Normalize();
Vector3 moveDir = camForward * input.y + camRight * input.x;
bool moving = moveDir.sqrMagnitude > 0.0001f;
// ----- หันหน้าไปทางที่เดิน -----
if (moving)
{
Quaternion targetRot = Quaternion.LookRotation(moveDir, Vector3.up);
transform.rotation = Quaternion.Slerp(
transform.rotation, targetRot, 1f - Mathf.Exp(-turnSpeed * Time.deltaTime));
}
// ----- ความเร็ว -----
float speed = GameInput.SprintHeld ? sprintSpeed : walkSpeed;
// ----- แรงโน้มถ่วง / กระโดด -----
if (controller.isGrounded && verticalVelocity < 0f)
verticalVelocity = -2f;
if (controller.isGrounded && GameInput.JumpPressed)
verticalVelocity = Mathf.Sqrt(jumpHeight * -2f * gravity);
verticalVelocity += gravity * Time.deltaTime;
Vector3 velocity = moveDir * speed;
velocity.y = verticalVelocity;
controller.Move(velocity * Time.deltaTime);
// ----- Animator -----
if (hasSpeedParam)
animator.SetFloat(speedHash, moving ? speed : 0f, 0.1f, Time.deltaTime);
}
}