using DG.Tweening; using Sirenix.OdinInspector; using SLSFramework.General; using UnityEngine; using Ease = DG.Tweening.Ease; namespace Cielonos.MainGame.Characters { public class CameraRotationSubmodule : SubmoduleBase { 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; } } */ } /// /// [新增] 触发相机战斗校准 /// /// 攻击的方向向量 (通常是 player.transform.forward) /// 校准持续时间 (建议 0.2f ~ 0.5f) 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; /// /// 同步相机旋转到当前摄像机朝向 /// 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); } } }