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

102 lines
3.5 KiB
C#
Raw 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 Core;
using UnityEngine;
namespace Player
{
/// <summary>
/// 玩家第一人称相机控制器
/// 挂到相机或相机父物体playerBody 指向角色的根 Transform用于左右旋转
/// </summary>
/// TODO:使用InputManager替换掉Input.GetAxis
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;
}
}
}