Files
2025TapTapGameJam/Assets/Script/Gameplay/Player/PlayerCameraController.cs

98 lines
3.5 KiB
C#
Raw Normal View History

using Core;
using UnityEngine;
using Script.Gameplay.Input;
namespace Script.Gameplay.Player
{
/// <summary>
/// 玩家第一人称相机控制器
/// 挂到相机或相机父物体playerBody 指向角色的根 Transform用于左右旋转
/// </summary>
public class PlayerCameraController : MonoBehaviour
{
[Header("References")] [Tooltip("角色根 Transform用于水平旋转yaw")]
public Transform playerBody;
[Tooltip("如果相机不是挂载在同一物体上,可以指定相机 Transform可选")]
public Transform cameraTransform;
[Header("Sensitivity & Invert")] [Tooltip("鼠标灵敏度")] [Range(0.01f, 1f)]
public float mouseSensitivity = 0.2f;
[Tooltip("反转垂直轴")] public bool invertY = false;
[Header("Vertical Limits")] [Tooltip("向上最大仰角(度)")]
public float maxUpAngle = 60f;
[Tooltip("向下最大俯角(度)")] public float maxDownAngle = 60f;
[Header("Smoothing")] public bool enableSmoothing = false;
[Tooltip("旋转平滑时间(秒)")] public float smoothTime = 0.05f;
// internal state
private float xRotation = 0f; // 垂直角pitch
private float yaw = 0f; // 水平角yaw
private float smoothVelocityPitch = 0f;
private float smoothVelocityYaw = 0f;
void Start()
{
if (cameraTransform == null)
cameraTransform = transform;
// 初始化当前角度以避免跳变
Vector3 euler = cameraTransform.localEulerAngles;
xRotation = NormalizeAngle(euler.x);
yaw = NormalizeAngle(playerBody ? playerBody.eulerAngles.y : transform.eulerAngles.y);
}
void Update()
{
Vector2 mouse = InputManager.Instance.Look;
// ✅ 不要乘 Time.deltaTime因为 Look 已经是每帧的增量
float mouseX = mouse.x * mouseSensitivity;
float mouseY = mouse.y * mouseSensitivity;
float invert = invertY ? 1f : -1f;
yaw += mouseX;
xRotation += mouseY * invert;
// 限制垂直角度
xRotation = Mathf.Clamp(xRotation, -maxDownAngle, maxUpAngle);
if (enableSmoothing)
{
float smoothPitch = Mathf.SmoothDampAngle(cameraTransform.localEulerAngles.x, xRotation,
ref smoothVelocityPitch, smoothTime);
float smoothYaw = Mathf.SmoothDampAngle(playerBody ? playerBody.eulerAngles.y : transform.eulerAngles.y,
yaw, ref smoothVelocityYaw, smoothTime);
cameraTransform.localRotation = Quaternion.Euler(smoothPitch, 0f, 0f);
if (playerBody)
playerBody.rotation = Quaternion.Euler(0f, smoothYaw, 0f);
else
transform.rotation = Quaternion.Euler(0f, smoothYaw, 0f);
}
else
{
cameraTransform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
if (playerBody)
playerBody.rotation = Quaternion.Euler(0f, yaw, 0f);
else
transform.rotation = Quaternion.Euler(0f, yaw, 0f);
}
}
// 将角度规范到 [-180,180] 范围,避免插值跳变
private float NormalizeAngle(float angle)
{
angle = (angle + 180f) % 360f - 180f;
return angle;
}
}
}