展前冒死重构

This commit is contained in:
FloatGaming
2026-07-24 04:43:13 +08:00
parent d09597472b
commit 4eb70b0ac9
61 changed files with 74951 additions and 328 deletions
@@ -38,10 +38,11 @@ public class effectEventController : MonoBehaviour
// 分辨率相机微调:改的是"漂移 pivot"(顶层节点,承载 -40°/-8 基准),不碰相机自身,
// 因此不与 SmoothShake(写相机 local)、技能偏移(写技能 pivot)、冲刺(写相机 z)冲突。
// 改 pivot 的 X 旋转无任何系统覆盖;改 pivot 的 Z 必须同步 cameraDriftBaseLocalPosition.z
// 否则 UpdateCameraDrift/ResetCameraDriftIfNeeded 会用旧基准把 z 拉回。
// 改 pivot 的 X 旋转无任何系统覆盖;改 pivot 的 Y/Z 必须同步 cameraDriftBaseLocalPosition
// 否则 UpdateCameraDrift/ResetCameraDriftIfNeeded 会用旧基准把 Y/Z 拉回。
private bool _cameraBaseCaptured;
private float _designPivotRotX; // pivot 初始 X 旋转(如 -40)
private float _designPivotY; // pivot 初始 Y(如 -6,相机高度)
private float _designPivotZ; // pivot 初始 Z(如 -8)
private void Awake()
@@ -117,16 +118,17 @@ public class effectEventController : MonoBehaviour
if (cachedCameraDriftPivot == null) return;
}
_designPivotRotX = cachedCameraDriftPivot.localEulerAngles.x;
_designPivotY = cachedCameraDriftPivot.localPosition.y;
_designPivotZ = cachedCameraDriftPivot.localPosition.z;
_cameraBaseCaptured = true;
}
/// <summary>
/// 按分辨率微调相机:在设计基准上叠加 X 旋转增量Z 位置增量。
/// 改的是漂移 pivot(不动相机本身),且同步 cameraDriftBaseLocalPosition.z
/// 按分辨率微调相机:在设计基准上叠加 X 旋转增量、Y 高度增量、Z 位置增量。
/// 改的是漂移 pivot(不动相机本身),且同步 cameraDriftBaseLocalPosition 的 y/z
/// 与漂移/抖动/技能偏移/冲刺全部不冲突。可重复调用(总是相对设计基准,不累积)。
/// </summary>
public void SetResolutionCameraAdjust(float extraRotX, float extraZ)
public void SetResolutionCameraAdjust(float extraRotX, float extraZ, float extraY = 0f)
{
CaptureCameraBaseIfNeeded();
if (cachedCameraDriftPivot == null) return;
@@ -136,12 +138,91 @@ public class effectEventController : MonoBehaviour
euler.x = _designPivotRotX + extraRotX;
cachedCameraDriftPivot.localEulerAngles = euler;
// Z:设计值 + 增量,并同步漂移基准 z(漂移只改 x,y,z 恒取基准)。
// Y(高度)与 Z:设计值 + 增量。漂移每帧写 base + (perlinX, perlinY, 0)
// 故必须同步 cameraDriftBaseLocalPosition 的 y/z,否则下一帧漂移会用旧基准拉回。
float targetY = _designPivotY + extraY;
float targetZ = _designPivotZ + extraZ;
Vector3 lp = cachedCameraDriftPivot.localPosition;
lp.y = targetY;
lp.z = targetZ;
cachedCameraDriftPivot.localPosition = lp;
cameraDriftBaseLocalPosition.z = targetZ; // 关键:否则会被 UpdateCameraDrift/Reset 拉回
cameraDriftBaseLocalPosition.y = targetY; // 关键:否则会被 UpdateCameraDrift/Reset 拉回
cameraDriftBaseLocalPosition.z = targetZ;
}
// 相机本体(Main Camera)分辨率适配的 local 基准。运行时相机被重挂到 skill_pivot 之下、
// local 位姿被清零(见 EnsureCameraDriftPivot/EnsureCameraSkillPivot),故基准 z≈0、X≈0。
// 首次调用 SetResolutionCameraSelf 时惰性捕获,供插值 t=0 回到该基准。
private bool _cameraSelfBaseCaptured;
private float _cameraSelfBaseLocalZ;
private float _cameraSelfBaseLocalRotX;
/// <summary>
/// 按分辨率**直接调整相机本体(Main Camera 子物体)**的 local z 高度与 local X 旋转,
/// 不动其父/祖父 pivot。t=0 → 回到相机 local 设计基准(运行时为 0/identity,与未调整一致)
/// t=1 → 相机 local 到达 (targetLocalRotX, targetLocalZ)。始终相对基准插值,不累积。
///
/// 冲突处理:相机本体的 local 由 SmoothShake(抖动时每帧写)与冲刺(动画 local z)共享。
/// - 空闲时二者不写相机(SmoothShake 无活动协程即不 ApplySum),本次写入持久生效;
/// - 抖动/冲刺触发时会以"当前 local"为基准重新捕获(SaveDefaultValues / CacheCameraTransform)
/// 故结束后回到本方法设定的值。为兼容"抖动进行中改分辨率"的罕见情形,
/// 若相机上已有 SmoothShake 且正在抖动,同步其 startPosition/startRotation 基准。
/// </summary>
public bool SetResolutionCameraSelf(float t, float targetLocalRotX, float targetLocalZ)
{
if (cachedShakeTarget == null)
{
CacheShakeTarget();
if (cachedShakeTarget == null) return false; // 相机(Camera.main)尚未就绪,稍后重试
}
t = Mathf.Clamp01(t);
if (!_cameraSelfBaseCaptured)
{
_cameraSelfBaseLocalZ = cachedShakeTarget.localPosition.z;
_cameraSelfBaseLocalRotX = NormalizeSignedAngle(cachedShakeTarget.localEulerAngles.x);
_cameraSelfBaseCaptured = true;
}
float z = Mathf.Lerp(_cameraSelfBaseLocalZ, targetLocalZ, t);
float rotX = Mathf.Lerp(_cameraSelfBaseLocalRotX, targetLocalRotX, t);
Vector3 lp = cachedShakeTarget.localPosition;
lp.z = z;
cachedShakeTarget.localPosition = lp;
Vector3 euler = cachedShakeTarget.localEulerAngles;
euler.x = rotX;
cachedShakeTarget.localEulerAngles = euler;
SyncShakeBaseIfActive(lp, euler);
return true;
}
// 若相机本体上的 SmoothShake 正在抖动,同步其 start 基准,避免抖动进行中改分辨率被回弹覆盖。
private void SyncShakeBaseIfActive(Vector3 localPos, Vector3 localEuler)
{
if (cachedShakeTarget == null) return;
var shake = cachedShakeTarget.GetComponent<SmoothShakeFree.SmoothShake>();
if (shake == null) return;
if (shake.activeShakeRoutines == null || shake.activeShakeRoutines.Count == 0) return;
var type = typeof(SmoothShakeFree.SmoothShake);
const System.Reflection.BindingFlags flags =
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance;
var startPosField = type.GetField("startPosition", flags);
var startRotField = type.GetField("startRotation", flags);
if (startPosField != null) startPosField.SetValue(shake, localPos);
if (startRotField != null) startRotField.SetValue(shake, localEuler);
}
// Unity eulerAngles.x 存 [0,360)-40 存成 320;归一到 [-180,180) 便于插值(负=朝上)。
private static float NormalizeSignedAngle(float angle)
{
angle %= 360f;
if (angle > 180f) angle -= 360f;
else if (angle < -180f) angle += 360f;
return angle;
}
private void PrewarmShakeComponent()