using System.Collections; using System.Collections.Generic; using UnityEngine; namespace SK.Framework { /// /// 自由相机控制器 /// WASD 移动,鼠标旋转,Q/E 上升下降,Shift 加速 /// [DisallowMultipleComponent] public class FreeCameraController : MonoBehaviour { #region Inspector 参数 [Header("控制总开关")] [Tooltip("是否启用相机控制")] public bool enableControl = true; [Tooltip("按住该鼠标键时才能旋转视角(0=左键,1=右键)")] public int lookMouseButton = 1; [Tooltip("旋转时是否锁定鼠标")] public bool lockCursor = true; [Header("移动参数(WASD)")] public float moveSpeed = 5f; public float moveDamping = 10f; [Header("Shift 加速")] [Tooltip("按住 Shift 时速度倍率")] public float shiftMultiplier = 2f; [Header("垂直移动(Q / E)")] [Tooltip("是否允许 Q/E 垂直移动")] public bool enableVerticalMove = true; public float verticalSpeed = 3f; public float minHeight = -10f; public float maxHeight = 50f; [Header("视角旋转")] public float mouseSensitivityX = 120f; public float mouseSensitivityY = 80f; [Tooltip("俯仰角最小值")] public float minPitch = -80f; [Tooltip("俯仰角最大值")] public float maxPitch = 80f; public float rotationDamping = 12f; #endregion #region 运行时状态 // 目标旋转角 private float yaw; private float pitch; // 平滑旋转角 private float smoothYaw; private float smoothPitch; // 目标移动速度 private Vector3 targetVelocity; private Vector3 smoothVelocity; #endregion #region Unity 生命周期 void Start() { // 初始化角度 Vector3 angles = transform.eulerAngles; yaw = angles.y; pitch = angles.x; smoothYaw = yaw; smoothPitch = pitch; } void Update() { if (!enableControl) return; HandleRotation(); HandleMovement(); } #endregion #region 视角旋转 /// /// 鼠标控制相机旋转 /// void HandleRotation() { if (!Input.GetMouseButton(lookMouseButton)) { // 松开鼠标时恢复光标 Cursor.lockState = CursorLockMode.None; Cursor.visible = true; return; } if (lockCursor) { Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; } yaw += Input.GetAxis("Mouse X") * mouseSensitivityX * Time.deltaTime; pitch -= Input.GetAxis("Mouse Y") * mouseSensitivityY * Time.deltaTime; pitch = Mathf.Clamp(pitch, minPitch, maxPitch); // 阻尼平滑 smoothYaw = Mathf.LerpAngle(smoothYaw, yaw, Time.deltaTime * rotationDamping); smoothPitch = Mathf.Lerp(smoothPitch, pitch, Time.deltaTime * rotationDamping); transform.rotation = Quaternion.Euler(smoothPitch, smoothYaw, 0f); } #endregion #region 移动控制 /// /// WASD + Q/E + Shift 移动 /// void HandleMovement() { Vector3 inputDir = Vector3.zero; // WASD 平移 float h = Input.GetAxis("Horizontal"); float v = Input.GetAxis("Vertical"); inputDir += transform.forward * v; inputDir += transform.right * h; // Q / E 垂直移动(可开关) if (enableVerticalMove) { if (Input.GetKey(KeyCode.E)) inputDir += Vector3.up; if (Input.GetKey(KeyCode.Q)) inputDir += Vector3.down; } inputDir = inputDir.normalized; // 基础速度 float currentSpeed = moveSpeed; // Shift 加速 if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) { currentSpeed *= shiftMultiplier; } // 目标速度 targetVelocity = inputDir * currentSpeed; // 阻尼平滑 smoothVelocity = Vector3.Lerp( smoothVelocity, targetVelocity, Time.deltaTime * moveDamping ); Vector3 nextPos = transform.position + smoothVelocity * Time.deltaTime; // 高度限制 nextPos.y = Mathf.Clamp(nextPos.y, minHeight, maxHeight); transform.position = nextPos; } #endregion } }