EnergyEfficiencyManagement/Assets/SKFramework/Tools/Camera/FreeCameraController.cs

187 lines
4.7 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SK.Framework
{
/// <summary>
/// 自由相机控制器
/// WASD 移动鼠标旋转Q/E 上升下降Shift 加速
/// </summary>
[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
/// <summary>
/// 鼠标控制相机旋转
/// </summary>
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
/// <summary>
/// WASD + Q/E + Shift 移动
/// </summary>
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
}
}