Unity摄像机鼠标右键旋转功能
实现功能
- 鼠标右键拖动旋转摄像机
- 支持水平(Y轴)和垂直(X轴)旋转
- 可调节的旋转速度
- 垂直旋转角度限制,防止视角翻转
- 平滑旋转效果
- 惯性旋转,拖动后释放鼠标仍有平滑过渡`
代码如下
using UnityEngine;
public class CameraRotation : MonoBehaviour
{[Header("旋转目标设置")][Tooltip("摄像机将围绕此目标点旋转")]public Transform target;[Tooltip("目标点与摄像机的初始距离")]public float distance = 5.0f;[Header("旋转参数")][Tooltip("旋转速度系数")]public float rotationSpeed = 2.0f;[Tooltip("垂直旋转最小角度限制")]public float verticalClampMin = -80f;[Tooltip("垂直旋转最大角度限制")]public float verticalClampMax = 80f;[Header("平滑旋转设置")][Tooltip("是否启用平滑旋转")]public bool useSmoothRotation = true;[Tooltip("平滑旋转时间")]public float smoothTime = 0.1f;[Header("惯性设置")][Tooltip("是否启用惯性旋转")]public bool useInertia = true;[Tooltip("惯性衰减因子")]public float inertiaFactor = 0.8f;[Tooltip("惯性停止阈值")]public float inertiaThreshold = 0.1f;[Header("键盘控制")][Tooltip("重置视角的按键")]public KeyCode resetKey = KeyCode.R;private Vector2 currentRotation;private Vector2 targetRotation;private Vector2 rotationVelocity;private Vector2 inertiaVelocity;private bool isRotating;private Vector3 lastMousePosition;private Vector2 initialRotation;void Start(){if (target == null){CreateDefaultTarget();}InitializeRotation();}void Update(){HandleInput();UpdateRotation();}private void CreateDefaultTarget(){GameObject targetObj = new GameObject("CameraTarget");targetObj.transform.position = transform.position + transform.forward * distance;target = targetObj.transform;}private void InitializeRotation(){Vector3 direction = target.position - transform.position;Quaternion rotation = Quaternion.LookRotation(direction);initialRotation.x = rotation.eulerAngles.x;initialRotation.y = rotation.eulerAngles.y;currentRotation = initialRotation;targetRotation = initialRotation;}private void HandleInput(){if (Input.GetMouseButtonDown(1)){StartRotation();}else if (Input.GetMouseButtonUp(1)){StopRotation();}if (isRotating){ProcessMouseMovement();}else if (useInertia){ProcessInertia();}if (Input.GetKeyDown(resetKey)){ResetView();}}private void StartRotation(){isRotating = true;lastMousePosition = Input.mousePosition;inertiaVelocity = Vector2.zero;}private void StopRotation(){isRotating = false;}private void ProcessMouseMovement(){Vector3 deltaMouse = Input.mousePosition - lastMousePosition;lastMousePosition = Input.mousePosition;targetRotation.y += deltaMouse.x * rotationSpeed * Time.deltaTime;targetRotation.x -= deltaMouse.y * rotationSpeed * Time.deltaTime;targetRotation.x = Mathf.Clamp(targetRotation.x, verticalClampMin, verticalClampMax);if (useInertia){inertiaVelocity = new Vector2(-deltaMouse.y, deltaMouse.x) * rotationSpeed;}}private void ProcessInertia(){if (inertiaVelocity.magnitude > inertiaThreshold){targetRotation.y += inertiaVelocity.y * Time.deltaTime;targetRotation.x += inertiaVelocity.x * Time.deltaTime;targetRotation.x = Mathf.Clamp(targetRotation.x, verticalClampMin, verticalClampMax);inertiaVelocity *= inertiaFactor;}else{inertiaVelocity = Vector2.zero;}}private void UpdateRotation(){if (useSmoothRotation){currentRotation = Vector2.SmoothDamp(currentRotation, targetRotation, ref rotationVelocity, smoothTime);}else{currentRotation = targetRotation;}ApplyRotation();}private void ApplyRotation(){transform.position = target.position;transform.rotation = Quaternion.Euler(currentRotation.x, currentRotation.y, 0f);transform.position -= transform.forward * distance;}public void ResetView(){targetRotation = initialRotation;inertiaVelocity = Vector2.zero;}void OnDrawGizmosSelected(){if (target != null){Gizmos.color = Color.yellow;Gizmos.DrawSphere(target.position, 0.1f);Gizmos.color = Color.cyan;Gizmos.DrawLine(transform.position, target.position);}}
}