using System.Collections; using System.Collections.Generic; using UnityEngine; public class FreeCameraController : MonoBehaviour { [Header("移动")] public float moveSpeed = 10f; public float fastSpeedMultiplier = 2f; [Range(0f, 1f)] public float moveSmooth = 0.15f; // 0=无平滑, 1=很丝滑 [Header("旋转")] public float rotateSpeed = 120f; // 角速度(度/秒),右键拖动 [Range(0f, 1f)] public float rotateSmooth = 0.12f; // 0=无平滑 public float minPitch = -80f, maxPitch = 80f; [Header("缩放/推进(滚轮)")] public float zoomSpeed = 8f; [Range(0f, 1f)] public float zoomSmooth = 0.15f; // 滚轮惯性 [Header("拖拽")] public float dragSpeed = 0.5f; // 中键左右拖动速度 [Header("按键")] public KeyCode fastKey = KeyCode.LeftShift; [Header("调试")] public bool showDebug = false; float yaw, pitch; Vector3 targetPos; Quaternion targetRot; // 滚轮惯性速度 float zoomVel = 0f; // 拖拽用 Vector3 lastMousePos; void Awake() { var e = transform.eulerAngles; yaw = e.y; pitch = e.x; targetPos = transform.position; targetRot = transform.rotation; } void Update() { ReadInput(); // 位置插值(moveSmooth=0 -> 立即到位) float mt = LerpFactor(moveSmooth); transform.position = Vector3.Lerp(transform.position, targetPos, mt); // 旋转插值(rotateSmooth=0 -> 立即到位) float rt = LerpFactor(rotateSmooth); transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, rt); } void ReadInput() { // —— 移动 —— // float speed = moveSpeed * (Input.GetKey(fastKey) ? fastSpeedMultiplier : 1f); Vector3 move = Vector3.zero; if (Input.GetKey(KeyCode.W)) move += transform.forward; if (Input.GetKey(KeyCode.S)) move -= transform.forward; if (Input.GetKey(KeyCode.D)) move += transform.right; if (Input.GetKey(KeyCode.A)) move -= transform.right; if (Input.GetKey(KeyCode.E)) move += transform.up; if (Input.GetKey(KeyCode.Q)) move -= transform.up; if (move.sqrMagnitude > 0f) targetPos += move.normalized * speed * Time.unscaledDeltaTime; // —— 旋转(右键)—— // if (Input.GetMouseButton(1)) { yaw += Input.GetAxis("Mouse X") * rotateSpeed * Time.unscaledDeltaTime; pitch -= Input.GetAxis("Mouse Y") * rotateSpeed * Time.unscaledDeltaTime; pitch = Mathf.Clamp(pitch, minPitch, maxPitch); targetRot = Quaternion.Euler(pitch, yaw, 0f); } // —— 滚轮推进(带惯性)—— // float scroll = Input.mouseScrollDelta.y; if (Mathf.Abs(scroll) > 0.001f) zoomVel += scroll * zoomSpeed; zoomVel = Mathf.Lerp(zoomVel, 0f, LerpFactor(zoomSmooth)); if (Mathf.Abs(zoomVel) > 0.0001f) targetPos += transform.forward * zoomVel * Time.unscaledDeltaTime; // —— 中键左右拖动 —— // if (Input.GetMouseButtonDown(2)) { lastMousePos = Input.mousePosition; } if (Input.GetMouseButton(2)) { Vector3 delta = Input.mousePosition - lastMousePos; lastMousePos = Input.mousePosition; // 只取 x 分量(左右拖动),用相机的 right 向量 Vector3 right = transform.right; targetPos -= right * delta.x * dragSpeed * Time.unscaledDeltaTime; } if (showDebug) Debug.Log($"move:{move} speed:{speed} scroll:{scroll} zoomVel:{zoomVel} pos:{transform.position}"); } float LerpFactor(float smooth) { if (smooth <= 0f) return 1f; return 1f - Mathf.Pow(1f - Mathf.Clamp01(smooth), Time.unscaledDeltaTime * 60f); } public void SnapTo(Transform target) { transform.position = target.position; transform.rotation = target.rotation; targetPos = target.position; targetRot = target.rotation; Vector3 euler = target.rotation.eulerAngles; yaw = euler.y; pitch = euler.x; } }