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