Files
zeling_v2/Docs/Verification/12_Manual_CameraSystem.md
2026-05-17 07:56:12 +08:00

501 lines
24 KiB
Markdown
Raw Permalink 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.
# 手动测试 12 · 区域相机系统
> **测试类型**Unity Editor 手动测试Play Mode
> **覆盖模块**`CameraArea`、`CameraTriggerZone`、`CameraStateController`、`CinemachineConfiner2D`、`CameraBlendProfileSO`
> **前置文档**`Phase1_Verification_Guide.md` §1验证前准备
---
## 快速工具
| 工具 | 用途 | 菜单路径 |
|------|------|----------|
| **Camera Area Setup窗口** | 扫描场景中所有 CameraArea/TriggerZone/Controller显示绑定状态提供一键修复 | `BaseGames → Camera → Camera Area Setup` |
| **Place Camera Area** | 生成 CameraArea 节点(含 PolygonCollider2D 限位边界) | `BaseGames → Scene → Place → Camera Area` |
| **Place Camera Trigger Zone** | 生成 CameraTriggerZone + BoxCollider2D Trigger | `BaseGames → Scene → Place → Camera Trigger Zone` |
**典型工作流**
1. 在 Persistent 场景中放置两台全局虚拟相机(`VCamA` / `VCamB`),绑定到 `CameraStateController._vcamA/_vcamB`
2. 在关卡场景中使用 **Place Camera Area** 为每个相机区域放置 `CameraArea` 数据节点(一个房间可放多个)。
3. 选中 `CameraArea`,在 Scene 视图中拖拽**黄色可视区域**的边 Handle 调整可见范围,然后点击 Inspector 底部 **「从可视区域更新限位区域(透视)」** 自动换算限位多边形。
4. 使用 **Place Camera Trigger Zone** 在区域入口放置触发器,并将目标 `CameraArea` 拖入 `_targetArea`
5. 打开 **Camera Area Setup** 窗口,点击 **为全局 VCam 赋值 Follow 目标**(会自动在 Player 下创建或复用 `CameraFollowTarget` 子节点并绑定)。
6. 所有条目显示绿色 ● → 进入 Play Mode 验证。
---
## 目录
1. [系统架构说明](#1-系统架构说明)
2. [Persistent 场景配置CameraStateController](#2-persistent-场景配置cameraStatecontroller)
3. [关卡场景配置CameraArea + CameraTriggerZone](#3-关卡场景配置cameraarea--cameratriggerzone)
4. [ScriptableObject 资产说明](#4-scriptableobject-资产说明)
5. [Camera Area Setup 工具详解](#5-camera-area-setup-工具详解)
6. [验收测试用例](#6-验收测试用例)
7. [常见问题排查](#7-常见问题排查)
---
## 1. 系统架构说明
```
Persistent.unity
└── [Camera]
└── CameraStateController ExecutionOrder = -100
组件: CameraStateController
│ _vcamA → VCamA全局虚拟相机 A
│ _vcamB → VCamB全局虚拟相机 B
│ _lookSystem → CameraLookSystem 节点
组件: CinemachineBrain ← 实际渲染相机(随 Main Camera 放置)
组件: CinemachineImpulseSource ← 屏幕抖动信号源
├── CameraLookSystem ← 运行时由 SetFollowTarget() 赋值基准目标
│ 组件: CameraLookSystem 双轴窥视偏移 + 速度门控;输出 VirtualTarget
├── VCamA
│ 组件: CinemachineCamera Follow = CameraLookSystem.VirtualTarget运行时自动赋值
│ 组件: CinemachinePositionComposer Body 跟随组件;初始值与 CameraArea 默认值对齐
│ 组件: CinemachineConfiner2D ← 由 CameraStateController 动态更新 BoundingShape2D
│ 组件: CameraAxisLockExtension 锁定 X 或 Y 轴(竖井 / 走廊场景)
│ 组件: CameraAsymmetricDampingExtension 非对称 Y 阻尼(下落快恢复,起跳慢追赶)
│ 组件: CameraAdaptiveLookaheadExtension 速度自适应 Lookahead移动快 → 预见更多)
└── VCamB
组件: CinemachineCamera Follow = CameraLookSystem.VirtualTarget运行时自动赋值
组件: CinemachinePositionComposer 同 VCamA
组件: CinemachineConfiner2D ← 由 CameraStateController 动态更新 BoundingShape2D
组件: CameraAxisLockExtension
组件: CameraAsymmetricDampingExtension
组件: CameraAdaptiveLookaheadExtension
Level_01.unity
├── [CameraAreas]
│ ├── CameraArea_A 区域 A可在同一房间内放置多个
│ │ 组件: CameraArea _confinerCollider → PolygonCollider2D
│ │ │ _visibleBounds可视矩形
│ │ │ _blendProfile → CameraBlendProfileSO可选
│ │ │ _dedicatedCamera专有 VCam可选priority > 全局)
│ │ └── PolygonCollider2D 定义该区域的相机限位边界
│ │
│ └── CameraArea_B 区域 B
│ ...(同上)
└── [Triggers]
├── CameraTriggerZone_AB 区域 A→B 入口
│ 组件: CameraTriggerZone _targetArea = CameraArea_B
│ 组件: BoxCollider2D isTrigger = true
└── CameraTriggerZone_BA 区域 B→A 入口
组件: CameraTriggerZone _targetArea = CameraArea_A
组件: BoxCollider2D isTrigger = true
```
**核心流程**
1. 玩家进入 `CameraTriggerZone``OnTriggerEnter2D` 调用 `ICameraService.SwitchArea(targetArea)`
2. `CameraStateController.SwitchArea` → 应用 `BlendProfile``CinemachineBrain.DefaultBlend`
- **无专有 VCam**:配置非活跃全局 VCam 的 `CinemachineConfiner2D.BoundingShape2D` → 提升其优先级至 10 → 降低旧 VCam 优先级至 0ping-pongCinemachine Brain 自动触发混合过渡
- **有专有 VCam**:提升 `_dedicatedCamera` 优先级至 `_dedicatedPriority`(默认 20高于全局 VCamCinemachine 自动切换
---
## 2. Persistent 场景配置CameraStateController
### 2.1 组件放置
在 Persistent 场景的 `[Camera]` 下建立以下节点结构:
| GameObject | 挂载组件 | 说明 |
|-----------|---------|------|
| `[CameraController]` | `CameraStateController``CinemachineBrain``CinemachineImpulseSource` | ExecutionOrder = -100 |
| `CameraLookSystem` | `CameraLookSystem` | 双轴窥视偏移(垂直+水平)+ 速度门控;输出 `VirtualTarget` 供 VCam 跟随;拖入 `CameraStateController._lookSystem` |
| `VCamA` | `CinemachineCamera`、**`CinemachinePositionComposer`**、`CinemachineConfiner2D``CameraAxisLockExtension``CameraAsymmetricDampingExtension``CameraAdaptiveLookaheadExtension` | 全局虚拟相机 A**PositionComposer 是 Body 组件,必须存在**;拖入 `CameraStateController._vcamA` |
| `VCamB` | `CinemachineCamera`、**`CinemachinePositionComposer`**、`CinemachineConfiner2D``CameraAxisLockExtension``CameraAsymmetricDampingExtension``CameraAdaptiveLookaheadExtension` | 全局虚拟相机 B同 VCamA拖入 `CameraStateController._vcamB` |
> **注意**`CinemachineBrain` 须挂在附有 `Camera` 组件Main Camera的 GameObject 上,
> 否则 Cinemachine 无法驱动视口渲染。两台全局 VCam 初始优先级均为 0由 `CameraStateController` 在运行时动态管理。
### 2.2 字段绑定清单
打开 **Camera Area Setup** 窗口(`BaseGames → Camera → Camera Area Setup`
**CameraStateController** 区域确认以下项目全为绿色 ●:
| 字段 | 期望状态 |
|------|---------|
| `_vcamA` (CinemachineCamera) | ● 已绑定 |
| `_vcamB` (CinemachineCamera) | ● 已绑定 |
| `_brain` (CinemachineBrain) | ● 已绑定 |
| `_lookSystem` (CameraLookSystem) | ● 已绑定 |
| `_impulseSource` (CinemachineImpulseSource) | ◌ 可选;用于屏幕抖动 |
| `_defaultBlendProfile` (CameraBlendProfileSO) | ◌ 可选;未设置则无混合过渡 |
---
## 3. 关卡场景配置CameraArea + CameraTriggerZone
### 3.1 添加 CameraArea
**方式 A使用快速放置工具**(推荐)
1. 菜单 `BaseGames → Scene → Place → Camera Area`
2. 工具自动创建以下节点结构:
```
CameraArea
├── CameraArea组件_confinerCollider 已绑定)
└── PolygonCollider2D默认矩形 24×12isTrigger = true定义限位区域
```
3. 打开 **Camera Area Setup** 窗口,点击 **为全局 VCam 赋值 Follow 目标**
(工具会自动在 Player 下查找或创建 `CameraFollowTarget` 子节点,绑定到两台全局 VCam
4. 手动调整子节点 `PolygonCollider2D` 顶点定义限位范围。
**方式 B手动创建**
1. 新建空 GameObject命名如 `CameraArea_A`
2. 挂载 `CameraArea`BaseGames.Camera
3. 在同一 GameObject 或子对象上创建 `PolygonCollider2D`
4. 将 `PolygonCollider2D` 拖入 `CameraArea._confinerCollider`
5. (可选)如需专有相机参数,新建独立 VCam GameObject挂载 `CinemachineCamera`,拖入 `CameraArea._dedicatedCamera`
> **一个房间可放置多个 `CameraArea`**,如大厅区域与 Boss 区域分别使用不同的限位和混合配置。
### 3.2 调整限位区域PolygonCollider2D
`CameraArea` 上(或子节点)的 `PolygonCollider2D` 定义了相机在该区域内的移动边界。
- **编辑顶点**:选中 `CameraArea` 节点 → Inspector 中 `PolygonCollider2D` → 点击 **Edit Collider** 图标,在 Scene 视图拖动顶点
- **自动修复**:打开 **Camera Area Setup** 窗口,对应条目点击 **修复:绑定子节点 PolygonCollider2D**
> **最佳实践**:限位区域应比实际可见范围大一格以上(约 1 unit避免相机卡在边缘。
### 3.3 添加 CameraTriggerZone
**使用快速放置工具**(推荐)
1. 菜单 `BaseGames → Scene → Place → Camera Trigger Zone`
2. 工具生成:
```
CameraTriggerZone
├── CameraTriggerZone组件_playerTag = "Player"
└── BoxCollider2DisTrigger = true默认 2×2
```
3. 在 Inspector 中将目标 `CameraArea` 拖入 `CameraTriggerZone._targetArea`
4. 调整 `BoxCollider2D` 大小至覆盖整个区域过渡走廊宽度(通常 2×3 或 2×4
**典型布局**
```
[区域 A] ‖ [走廊] ‖ [区域 B]
←← TriggerZone_A→B (_targetArea = CameraArea_B)
TriggerZone_B→A (_targetArea = CameraArea_A) →→
```
> 双向过渡需要两个 TriggerZone 分别放置在走廊两端,各自指向对应区域的 `CameraArea`。
### 3.4 全局 VCam Follow 绑定
Persistent 场景中两台全局 VCam 的 `CinemachineCamera.Follow` **不直接指向 Player**
而是指向 `CameraLookSystem` 组件在运行时生成的 **`[CameraLookTarget]` 虚拟目标节点**。
该节点由 `CameraStateController.SetFollowTarget(Transform)` 在玩家注册时自动创建并赋值,
其世界位置 = Player 基准目标位置 + 当前窥视偏移(`CameraLookSystem` 的双轴输出)。
> **不要在 Inspector 中手动把 VCam.Follow 拖到 Player 本身或 Player/CameraFollowTarget。**
> `SetFollowTarget` 会在运行时覆盖,且直接指向 Player 会绕过窥视偏移计算。
**工具支持**
**Camera Area Setup** 窗口 → **为全局 VCam 赋值 Follow 目标** 按钮
→ 该按钮仅用于调试回退(绕过 LookSystem直指 Player/CameraFollowTarget
正式流程请通过 `ICameraService.SetFollowTarget(playerTransform)` 注册,由系统自动处理。
---
### 3.5 编辑可视区域(透视相机)
`CameraArea` 支持在 Scene 视图中直接定义摄像机的最大可视范围,并自动换算为限位 `PolygonCollider2D` 的顶点坐标。
**Inspector 字段**
| 字段 | 说明 |
|------|------|
| `_visibleBounds` | 摄像机应显示的最大可视矩形世界坐标Scene 视图选中时显示为**黄色矩形** |
| `_cameraDepth` | 摄像机到场景平面Z = 0的垂直距离留 `0` 则自动读取 `\|transform.position.z\|` |
**Scene 视图拖拽编辑**
选中 `CameraArea` GameObject 后Scene 视图出现:
- **黄色矩形**:可视区域(玩家在此区域内的最大可见范围)
- **蓝色多边形**:当前 `PolygonCollider2D` 限位边界(参考用)
矩形四条边各有一个滑动 Handle拖拽即可调整
- 左 / 右边 Handle沿 X 轴滑动
- 上 / 下边 Handle沿 Y 轴滑动
**同步到限位区域**
调整好可视区域后,在 Inspector 底部点击 **「从可视区域更新限位区域(透视)」**,工具根据以下公式换算限位多边形:
```
halfH = depth × tan(vFOV / 2)
halfW = halfH × aspectRatio
confiner = visibleBounds 向内收缩 (halfW, halfH)
```
> **含义**相机视口边缘恰好与可视区域边框对齐。若区域小于单屏inset 后为负),限位收缩为中心点,相机固定居中。
Inspector 参数预览区实时显示 FOV来源专有 VCam → 全局 VCamA → Camera.main → 60°、深度、视口半宽 / 半高的计算值。
### 3.6 专有 VCam特殊区域
需要独特相机参数(如 Boss 区域特写 FOV的区域可在 `CameraArea._dedicatedCamera` 中指定一台独立的 `CinemachineCamera`
1. 在关卡场景中新建空 GameObject挂载 `CinemachineCamera`(设置好 Lens、Follow、Noise 等参数)
2. 将其拖入该 `CameraArea._dedicatedCamera`
3. `_dedicatedPriority`(默认 20须高于全局 VCam 的激活优先级10
进入该区域时,`CameraStateController` 自动提升专有 VCam 优先级Cinemachine 混合切换;离开时优先级归零,全局 VCam 重新接管。
---
## 4. ScriptableObject 资产说明
### 4.1 CameraBlendProfileSO
**创建路径**`Assets → Create → BaseGames → Camera → BlendProfile`
| 字段 | 说明 | 典型值 |
|------|------|--------|
| `Style` | 混合曲线类型EaseInOut / Linear / Cut / Custom | `EaseInOut` |
| `BlendTime` | 混合持续时间(秒) | `0.5` |
| `CustomCurve` | 仅 `Style = Custom` 时使用 | — |
**使用**
- 全局默认:拖入 `CameraStateController._defaultBlendProfile`
- 单独区域:拖入对应 `CameraArea._blendProfile`(覆盖全局默认)
### 4.2 CameraConfigSO
> ⚠ **Legacy / 已废弃**`CameraConfigSO` 是早期相机系统的配置资产,现已不再被 `CameraStateController` 读取或应用。
> 当前架构直接通过 `CameraArea` 字段(`ScreenPosition`、`DeadZoneSize`、`LookaheadTime`、`DampingDown`、`DampingUp` 等)在 `ConfigureSlot` 时写入 Cinemachine 组件,无需此 SO。
> 若项目中仍存在 `CameraConfigSO` 资产,可安全忽略或删除。
~~**创建路径**`Assets → Create → BaseGames → Camera → CameraConfig`~~
| 字段 | 说明 | 典型值 |
|------|------|--------|
| `FollowDamping` | ~~跟随阻尼~~ | — |
| `LookAheadTime` | ~~朝向预见时间~~ | — |
| `DeadZoneSize` | ~~死区尺寸~~ | — |
| `SoftZoneSize` | ~~软区尺寸~~ | — |
| `LookDownOffset` | ~~俯视偏移~~ | — |
| `LookUpOffset` | ~~仰视偏移~~ | — |
| `DefaultImpulseStrength` | ~~默认震屏强度~~ | — |
> `CameraConfigSO` 的配置值须由运行时的 `CameraStateController` 或相机系统读取并写入 Cinemachine 组件,具体写入逻辑取决于 `CameraStateController.ApplyConfig()` 的实现(如有扩展)。
---
## 5. Camera Area Setup 工具详解
菜单:`BaseGames → Camera → Camera Area Setup`
### 5.1 界面区域说明
**工具栏**
- `↻ 刷新`:手动重新扫描当前已加载场景
- `Place Camera Area`:快捷调用 `BaseGames → Scene → Place → Camera Area`
- `Place Trigger Zone`:快捷调用 `BaseGames → Scene → Place → Camera Trigger Zone`
**CameraStateController 区域**
显示控制器组件绑定状态。若显示"未找到"提示,说明 Persistent 场景未加载(属正常)。
| 图标 | 含义 |
|------|------|
| ``(绿) | 项目已正确配置 |
| ``(红) | 缺失必填项 |
| ``(黄) | 可选项未设置 |
检查项:`_vcamA`、`_vcamB`(必填)、`_brain`(必填)、`_lookSystem`(必填)、`_impulseSource`(可选)、`_defaultBlendProfile`(可选)
底部按钮:**为全局 VCam 赋值 Follow 目标** → 查找 Player/CameraFollowTarget 并写入两台 VCam 的 Follow 字段。
**Camera Areas 区域**
为每个 `CameraArea` 显示一行,检查项:
| 字段 | 状态 |
|------|------|
| `_confinerCollider` (PolygonCollider2D) | 必填 |
| `_dedicatedCamera`(专有 VCam | 可选 |
| `_blendProfile` | 可选 |
每行可点击 **修复:绑定子节点 PolygonCollider2D** 自动修复 `_confinerCollider` 未绑定的情况。
**Camera Trigger Zones 区域**
列出所有 `CameraTriggerZone`,高亮显示 `_targetArea` 未绑定的项目(红色 ✗)。
### 5.2 典型使用流程
```
1. 打开窗口 BaseGames → Camera → Camera Area Setup
2. (仅首次)加载 Persistent 场景,确认 _vcamA/_vcamB/_brain 全绿
3. 在关卡场景中使用 Place Camera Area × N一个房间可放多个
4. 选中每个 CameraArea在 Scene 视图拖拽黄色可视区域边 Handle点击 [从可视区域更新限位区域(透视)]
5. 点击 [为全局 VCam 赋值 Follow 目标](自动创建 Player/CameraFollowTarget 并绑定)
6. 使用 Place Trigger Zone 添加 N 个触发器,手动绑定 _targetArea
7. 所有条目绿色 ● → 进入 Play Mode 验证
```
---
## 6. 验收测试用例
### 测试前检查清单
| # | 检查项 | 操作 |
|---|--------|------|
| 1 | Console 无红色 Error | `Window → General → Console` |
| 2 | **Camera Area Setup** 窗口所有必填项为绿色 ● | `BaseGames → Camera → Camera Area Setup` |
| 3 | Player 已在场景中tag = Player | Hierarchy |
| 4 | Physics2D Layer 矩阵已配置 | `BaseGames → Tools → Validate Physics2D Layer Matrix` |
---
### MT-CAM-01全局 VCam 正常跟随
**目的**:验证全局 VCam 激活后 `CinemachineCamera` 跟随玩家移动。
**步骤:**
1. Persistent 场景中放置 VCamA/VCamB`Follow = Player/CameraFollowTarget`
2. 关卡场景中放置一个 `CameraArea`,通过 `CameraTriggerZone` 或 `RoomController` 触发 `SwitchArea`
3. 按 **Play**,在 Scene 视图和 Game 视图同时观察
4. 用 WASD/方向键移动 Player
**预期结果:**
| 检查点 | 期望 | ✓ |
|--------|------|---|
| Game 视图相机跟随 Player 移动 | 玩家靠近边缘时相机平滑跟进 | ☐ |
| 相机不会越出 CameraArea 的限位范围 | 玩家走到边角时相机贴边停止 | ☐ |
| 无跳变(平滑)跟随 | 无抖动、跳帧 | ☐ |
---
### MT-CAM-02区域相机切换CameraTriggerZone
**目的**:验证玩家穿越触发器后全局 VCam ping-pong 平滑过渡到目标区域。
**步骤:**
1. 场景中放置两个 `CameraArea`A、B各有独立 `PolygonCollider2D` 限位
2. 在两区域之间放置两个 `CameraTriggerZone`(各自 `_targetArea` 互指)
3. 按 **Play**,引导 Player 穿越触发区进入区域 B
**预期结果:**
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 穿越触发器后 Game 视图开始混合过渡 | 相机平滑从 A 过渡到 B非切割 | ☐ |
| 过渡时长约等于 `CameraBlendProfileSO.BlendTime` | 与 SO 设置一致(默认 0.5s | ☐ |
| 过渡后相机限位在 CameraArea_B 的边界内 | 玩家无法把相机带出 B 的限位范围 | ☐ |
| 反向穿越触发器后相机切回 A | 同上,反向过渡 | ☐ |
---
### MT-CAM-03CinemachineConfiner2D 边界限位
**目的**:验证 `CinemachineConfiner2D` 正确将相机限制在 `CameraArea` 限位范围内。
**步骤:**
1. 打开关卡场景,确认 `CameraArea._confinerCollider` 已绑定,且 `CameraStateController` 已调用 `SwitchArea`
2. 按 **Play**,将 Player 移动到房间的各个角落和边缘
**预期结果:**
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 相机在所有方向均不超出 `PolygonCollider2D` 多边形范围 | 无越界 | ☐ |
| 小房间(相机视口 > 房间)时相机居中,不晃动 | 稳定居中 | ☐ |
**常见失败原因**
- `CameraArea._confinerCollider` 未绑定 → 打开 Camera Area Setup 点击修复
- PolygonCollider2D 顶点数量少于 3 → 确认 `_confinerCollider` 路径顶点完整
---
### MT-CAM-04屏幕抖动CinemachineImpulseSource
**目的**:验证调用 `ICameraService.TriggerImpulse` 时 Game 视图画面抖动。
**步骤:**
1. 确认 `CameraStateController._impulseSource` 已绑定
2. 按 **Play**
3. 在 Console 执行(或通过游戏内事件触发):
```csharp
ServiceLocator.Get<ICameraService>().TriggerImpulse(0.5f);
```
或让玩家受到一次伤害(若伤害系统已接入抖动调用)
**预期结果:**
| 检查点 | 期望 | ✓ |
|--------|------|---|
| Game 视图画面发生轻微抖动后恢复稳定 | 抖动时长约 0.20.4s,幅度可见 | ☐ |
| 无 Console 错误 | 无 NullReferenceException | ☐ |
---
### MT-CAM-05初始场景无 CameraStateController 时安全降级
**目的**:验证场景中未加载 Persistent 场景时,`CameraTriggerZone` 不崩溃。
**步骤:**
1. 单独打开关卡场景(不加载 Persistent.unity
2. 按 **Play**,移动 Player 穿越 `CameraTriggerZone`
**预期结果:**
| 检查点 | 期望 | ✓ |
|--------|------|---|
| 无 NullReferenceException | `ServiceLocator.GetOrDefault<ICameraService>()` 返回 null 时跳过 | ☐ |
| Console 可能有黄色 Warning服务未注册 | 无红色 Error | ☐ |
---
### MT-CAM-06多场景加载时相机状态正确恢复
**目的**:验证通过 `SceneLoader` 加载新场景时,`CameraStateController` 正确切换到新场景首个 `CameraArea`。
**步骤:**
1. 以 Persistent + Level_01 双场景启动
2. 按 **Play**,触发场景加载切换到 Level_02
3. Level_02 加载完成后观察相机
**预期结果:**
| 检查点 | 期望 | ✓ |
|--------|------|---|
| Level_02 的 `RoomController` 调用 `SwitchArea` 后相机切换正确 | 无黑屏、无旧场景相机残影 | ☐ |
| 旧场景 `CameraArea` 随场景卸载,全局 VCam 状态不受干扰 | 无相机混合错误 | ☐ |
> **注意**:全局 VCam 常驻 Persistent 场景,`CinemachineConfiner2D.BoundingShape2D` 在 `SwitchArea` 时动态更新,
> 旧场景卸载后引用会变为 null须确保 `SwitchArea` 在新场景 `CameraArea` 可用后再调用。
---
## 7. 常见问题排查
| 现象 | 原因 | 解决 |
|------|------|------|
| Game 视图相机不动(黑屏或固定位置) | 全局 VCam `Follow` 未绑定 | `ICameraService.SetFollowTarget(player)` 注册玩家;或 Camera Area Setup → 为全局 VCam 赋值 Follow 目标 |
| 相机追赶卡顿/震颤 | `CinemachineConfiner2D.BoundingShape2D` 未绑定或碰撞体顶点有误 | 确认 `CameraArea._confinerCollider` 已绑定PolygonCollider2D 顶点数 ≥ 3 |
| 进入区域后限位未更新(仍在旧区域限位内) | `CameraArea._confinerCollider` 为空,`ConfigureSlot` 跳过了更新 | 打开 Camera Area Setup 修复 `_confinerCollider` 绑定 |
| 场景中有多个 `CinemachineBrain` | Persistent 场景外又添加了含 Camera 组件的对象 | 仅 Main Camera 上保留一个 Brain |
| 过渡时画面闪切而非混合 | `CameraBlendProfileSO.BlendTime = 0` 或 Style = Cut | 检查 BlendProfile 并将 BlendTime 设置为 > 0 |
| `CameraStateController` 未找到Console 错误) | Persistent 场景未加载 | 确认 Build Settings 中 Persistent.unity 第一位;开发测试用 `SceneManager.LoadScene("Persistent", Additive)` |
| 触发器无响应(玩家穿越后相机不切) | `CameraTriggerZone._targetArea` 未绑定,或 `_playerTag` 不匹配 | 检查 `_targetArea` 是否已拖入 `CameraArea`;确认 Player Tag = "Player" |
| `Camera Area Setup` 窗口列表为空 | 场景未保存或 DomainReload 后未刷新 | 点击窗口内 `↻ 刷新` 按钮 |
| 专有 VCam 不切换 | `_dedicatedPriority` ≤ 全局激活优先级(默认 10 | 将 `_dedicatedPriority` 设置为 > 10默认 20 已满足) |
| Camera Area Setup 中 `_lookSystem` 红色 ✗ | `CameraStateController._lookSystem` 未绑定 | 将 Persistent 场景 `[Camera]/CameraLookSystem` 节点拖入该字段;或重新运行 SceneScaffoldTools |
| 按住方向键相机偏移不出现(窥视无效) | `CameraLookSystem._baseTarget` 未设置 | 确认 `ICameraService.SetFollowTarget(player)` 在玩家 Awake/Start 后调用 |
| 下落时相机跟随过慢(非对称阻尼异常) | `CameraAsymmetricDampingExtension` 未挂到 VCamA/VCamB或 `DampingDown` 未被 `ConfigureSlot` 写入 | 确认两台 VCam 已挂载该扩展;检查 `CameraArea._dampingDown` > 0 |
| 高速移动时 Lookahead 不变化 | `CameraAdaptiveLookaheadExtension` 未挂到 VCamA/VCamB或 `SetConfiguredMax` 未被调用 | 确认两台 VCam 已挂载该扩展;检查 `ConfigureSlot` 代码路径正常执行 |