52 lines
2.6 KiB
C#
52 lines
2.6 KiB
C#
using UnityEngine;
|
||
using Unity.Cinemachine;
|
||
|
||
namespace BaseGames.Camera
|
||
{
|
||
/// <summary>
|
||
/// Cinemachine 扩展:在 Body 阶段之后硬锁定相机某一轴向。
|
||
///
|
||
/// 用途:
|
||
/// - <see cref="LockX"/> = true → 垂直竖井 / 电梯:相机仅上下移动,X 固定于限位区域中心。
|
||
/// - <see cref="LockY"/> = true → 水平走廊:相机仅左右移动,Y 固定于限位区域中心。
|
||
///
|
||
/// 由 <see cref="CameraStateController"/> 在切换区域时自动写入 <see cref="LockedX"/> /
|
||
/// <see cref="LockedY"/>(从 ConfinerCollider.bounds.center 取值)并切换锁定开关。
|
||
/// </summary>
|
||
[AddComponentMenu("Cinemachine/Extensions/Camera Axis Lock")]
|
||
[DisallowMultipleComponent]
|
||
public class CameraAxisLockExtension : CinemachineExtension
|
||
{
|
||
/// <summary>锁定 X 轴(垂直竖井)。</summary>
|
||
[HideInInspector] public bool LockX = false;
|
||
/// <summary>锁定 Y 轴(水平走廊)。</summary>
|
||
[HideInInspector] public bool LockY = false;
|
||
/// <summary>X 轴锁定到的世界坐标(由 CameraStateController 写入)。</summary>
|
||
[HideInInspector] public float LockedX = 0f;
|
||
/// <summary>Y 轴锁定到的世界坐标(由 CameraStateController 写入)。</summary>
|
||
[HideInInspector] public float LockedY = 0f;
|
||
|
||
protected override void PostPipelineStageCallback(
|
||
CinemachineVirtualCameraBase vcam,
|
||
CinemachineCore.Stage stage,
|
||
ref CameraState state,
|
||
float deltaTime)
|
||
{
|
||
if (stage != CinemachineCore.Stage.Body) return;
|
||
|
||
// 通过覆写 PositionCorrection 而非 RawPosition 来锁定轴向。
|
||
// 最终相机位置 = RawPosition + PositionCorrection。
|
||
// 只修改 PositionCorrection 可确保:
|
||
// - 锁定轴:final = RawPos + (LockedVal - RawPos) = LockedVal,无论 Confiner 之前写入了什么修正量
|
||
// - 非锁定轴:保留 CinemachineConfiner3D 已计算好的 PositionCorrection,限位正常生效
|
||
// 若改为修改 RawPosition,在 Confiner 之后运行时会导致
|
||
// final = LockedVal + ConfinementCorrection ≠ LockedVal,使 Confiner 修正量错误叠加。
|
||
var rawPos = state.RawPosition;
|
||
var correction = state.PositionCorrection;
|
||
if (LockX) correction.x = LockedX - rawPos.x;
|
||
if (LockY) correction.y = LockedY - rawPos.y;
|
||
state.PositionCorrection = correction;
|
||
}
|
||
}
|
||
}
|