Files
Cielonos/Assets/Scripts/MainGame/Characters/Player/View/CameraRotationSubmodule.cs
SoulliesOfficial 2a2aa728d5 切换主武器
2025-12-23 19:47:06 -05:00

145 lines
5.6 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 DG.Tweening;
using Sirenix.OdinInspector;
using SLSFramework.General;
using UnityEngine;
using Ease = DG.Tweening.Ease;
namespace Cielonos.MainGame.Characters
{
public class CameraRotationSubmodule : SubmoduleBase<PlayerViewSubcontroller>
{
private Player player => owner.player;
private PlayerViewSubcontroller viewSc => owner;
private PlayerInputSubcontroller inputSc => player.inputSc;
private const float RotateThreshold = 0.01f;
[Title("Cinemachine Settings")]
public float cinemachineTargetYaw;
public float cinemachineEndLockYaw;
public float cinemachineTargetPitch;
public float topClamp = 70.0f;
public float bottomClamp = -30.0f;
public bool lockCameraPosition = false;
[Title("Combat Recenter Settings")]
public float recenterSmoothTime = 0.1f; // 平滑时间,越小转得越快
private float recenterVelocity; // SmoothDamp使用的速度变量
private float targetRecenterYaw; // 目标角度
private bool isRecentering = false; // 是否正在校准
private float recenterTimer = 0.0f; // 校准剩余时间
public CameraRotationSubmodule(PlayerViewSubcontroller owner, float initialYaw) : base(owner)
{
this.cinemachineTargetYaw = initialYaw;
}
public void Update()
{
if (inputSc.Look.sqrMagnitude >= RotateThreshold && !lockCameraPosition)
{
isRecentering = false;
float deltaTimeMultiplier = inputSc.CurrentScheme == "KeyboardMouse" ? 1.0f : Time.deltaTime;
//if (!viewSc.lockTargetModule.isLockedMelee)
{
cinemachineTargetYaw += inputSc.Look.x * deltaTimeMultiplier;
cinemachineTargetPitch += inputSc.Look.y * deltaTimeMultiplier;
}
}
else if (isRecentering)
{
recenterTimer -= Time.deltaTime;
if (recenterTimer <= 0)
{
isRecentering = false;
}
else
{
cinemachineTargetYaw = Mathf.SmoothDampAngle(cinemachineTargetYaw, targetRecenterYaw, ref recenterVelocity, recenterSmoothTime);
}
}
cinemachineTargetYaw = MathExtensions.ClampAngle(cinemachineTargetYaw, float.MinValue, float.MaxValue);
cinemachineTargetPitch = MathExtensions.ClampAngle(cinemachineTargetPitch, bottomClamp, topClamp);
if (viewSc.lockTargetModule.isUsingLockTargetCamera)
{
cinemachineEndLockYaw = viewSc.lockingTargetCamera.transform.eulerAngles.y;
}
else
{
viewSc.cameraRoot.rotation = Quaternion.Euler(
cinemachineTargetPitch /*- viewSc.muzzleLiftModule.currentMuzzlePositionY*/, cinemachineTargetYaw, 0.0f);
}
/*
if (player.motionController.characterRotationType == PlayerMotionController.CharacterRotationType.ByAiming)
{
player.transform.rotation = Quaternion.Euler(0.0f, cinemachineTargetYaw, 0.0f);
if (viewSc.lockTargetModule.isLockedMelee)
{
//cinemachineEndLockYaw = player.viewController.lockingCamera.transform.eulerAngles.y;
//player.transform.rotation = Quaternion.Euler(0.0f, cinemachineEndLockYaw, 0.0f);
}
}
else
{
if (viewSc.lockTargetModule.isLockedMelee)
{
cinemachineEndLockYaw = viewSc.lockingCamera.transform.eulerAngles.y;
}
}
*/
}
/// <summary>
/// [新增] 触发相机战斗校准
/// </summary>
/// <param name="attackDirection">攻击的方向向量 (通常是 player.transform.forward)</param>
/// <param name="duration">校准持续时间 (建议 0.2f ~ 0.5f)</param>
public void TriggerCameraRecenter(Vector3 attackDirection, float duration = 0.2f)
{
if (attackDirection.sqrMagnitude < 0.01f) return;
// 计算目标角度
Quaternion targetRot = Quaternion.LookRotation(attackDirection);
targetRecenterYaw = targetRot.eulerAngles.y;
// 激活状态
recenterTimer = duration;
isRecentering = true;
}
private bool tt;
/// <summary>
/// 同步相机旋转到当前摄像机朝向
/// </summary>
public void SyncRotationWithCamera()
{
// 确保获取的是当前正在起作用的锁定相机的旋转
var camera = viewSc.currentCamera;
Vector3 currentEuler = camera.transform.eulerAngles;
float yaw = currentEuler.y;
float pitch = currentEuler.x;
// --- 核心修复:处理欧拉角跨度问题 ---
// 如果 pitch > 180 (例如 355), 则转为负数 ( -5 )
if (pitch > 180) pitch -= 360;
isRecentering = false;
// 更新目标值
cinemachineTargetYaw = yaw;
cinemachineTargetPitch = pitch;
// --- 立即应用旋转 ---
// 强制立即更新一次 cameraRoot防止等待下一帧 Update 产生的跳变
viewSc.cameraRoot.rotation = Quaternion.Euler(cinemachineTargetPitch, cinemachineTargetYaw, 0.0f);
}
}
}