地图系统

This commit is contained in:
2026-06-05 18:41:33 +08:00
parent 613f2a4d13
commit fe4fd60083
234 changed files with 33090 additions and 4899 deletions

View File

@@ -0,0 +1,299 @@
# Persistent 场景配置手册
> 文件位置:`Docs/Guides/03_Persistent_Scene_Setup_Guide.md`
> 版本1.0 · 适用项目zeling_v2
---
## 目录
1. [架构概览](#1-架构概览)
2. [快速开始:脚手架工具](#2-快速开始脚手架工具)
3. [自动生成内容速查](#3-自动生成内容速查)
4. [手动配置项详解](#4-手动配置项详解)
- 4.1 [SceneFade配置 MMF_Player 淡入淡出效果](#41-scenefade配置-mmf_player-淡入淡出效果)
- 4.2 [SplashScreenController美术资源替换](#42-splashscreencontroller美术资源替换)
- 4.3 [LoadingScreenManager背景图与提示文字](#43-loadingscreenmanager背景图与提示文字)
- 4.4 [HUDControllerUI 资源绑定](#44-hudcontroller-ui-资源绑定)
- 4.5 [AudioManagerAudioMixer 指定](#45-audiomanager-audiomixer-指定)
- 4.6 [PauseMenuController按钮文本与样式](#46-pausemenucontroller按钮文本与样式)
5. [事件频道速查表](#5-事件频道速查表)
6. [场景切换完整时序](#6-场景切换完整时序)
7. [常见问题排查](#7-常见问题排查)
---
## 1. 架构概览
Persistent 场景在整个游戏生命周期内**常驻内存**,承载所有跨场景的全局系统。
游戏场景(关卡、主菜单等)以 Additive 方式叠加在它之上。
```
[Persistent Scene]
├── [SERVICES] ← 纯逻辑SceneService, GameManager, AudioManager ...
└── [UI]
├── UIRoot ← UIManager面板栈管理
│ ├── HUD Canvas / HUDRoot
│ ├── DeathScreen Canvas / DeathScreenRoot
│ ├── PauseMenuRoot
│ ├── SettingsRoot
│ ├── MapRoot
│ └── ShopRoot
├── Canvas_Splash ← SplashScreenController启动演出
├── Canvas_Loading ← LoadingScreenManager加载遮罩
└── SYS_SceneFade ← SceneFadeController场景切换黑幕
├── FeedbackFadeOut ← SceneFeedback + MMF_Player ★需手动配置
└── FeedbackFadeIn ← SceneFeedback + MMF_Player ★需手动配置
```
**调用链(场景切换):**
```
RoomTransition / DoorTransition游戏场景
→ ServiceLocator<ISceneService>.RequestTransition(request)
→ SceneService.LoadSceneCoroutine()
→ EVT_FadeOutRequest.Raise()
→ 等待 _sceneFadeDuration默认 0.4 s
→ 加载目标场景
→ EVT_FadeInRequest.Raise()
EVT_FadeOutRequest / EVT_FadeInRequest
→ SceneFadeControllerPersistent 场景)
→ SceneFeedback.Play()
→ MMF_Player.PlayFeedbacks() ← 实际视觉效果在此配置
```
---
## 2. 快速开始:脚手架工具
**空的 Persistent 场景** 中执行:
```
菜单栏 → BaseGames → Scene → Setup → Scaffold Persistent Scene
```
脚手架完成后会在编辑器底部输出一份报告,列出所有已自动绑定的内容及仍需手动处理的项目。
**请务必阅读该报告再继续。**
> **前提条件**
> 运行脚手架前,先执行 `BaseGames → Scene → Setup → Create All Event Channel Assets`
> 确保所有事件频道 SO 资产已生成,脚手架才能自动绑定引用。
---
## 3. 自动生成内容速查
脚手架会自动完成以下所有节点的创建与字段绑定:
| 节点 / 组件 | 自动创建子节点 | 自动绑定字段 |
|---|---|---|
| `UIRoot / UIManager` | HUD Canvas、DeathScreen Canvas、PauseMenuRoot、SettingsRoot、MapRoot、ShopRoot | `_hudRoot``_deathScreenRoot``_addressablePanelParent``_panels[4]`、全部事件频道 |
| `DeathScreenRoot / DeathScreenController` | `RespawnButton`Button`DeathMessage`TextMeshProUGUI | `_btnRespawn``_deathMessage``_onDeathScreenConfirmed` |
| `PauseMenuRoot / PauseMenuController` | `Btn_Resume``Btn_Settings``Btn_MainMenu``Btn_Quit`(各带 Button | 4 个按钮引用、`_onResumeRequested``_onSceneLoadRequest` |
| `Canvas_Splash / SplashScreenController` | `StudioLogo`CanvasGroup`GameTitle`CanvasGroup | `_splashRoot``_studioLogoGroup``_gameTitleGroup`、事件频道 |
| `Canvas_Loading / LoadingScreenManager` | `LoadingRoot``ProgressBarFill`Image.Filled`TipText`TextMeshProUGUI | `_loadingRoot``_progressFill``_tipText`、事件频道 |
| `SYS_SceneFade / SceneFadeController` | `FeedbackFadeOut`MMF_Player + SceneFeedback`FeedbackFadeIn`MMF_Player + SceneFeedback | `_fadeOut``_fadeIn``_onFadeOutRequest``_onFadeInRequest` |
---
## 4. 手动配置项详解
### 4.1 SceneFade配置 MMF_Player 淡入淡出效果
这是**唯一的核心视觉必配项**,脚手架已创建好节点和组件,但 `MMF_Player` 内部的具体效果需要手动添加。
**节点路径:**
```
[UI] → SYS_SceneFade → FeedbackFadeOut (淡出:画面变黑)
[UI] → SYS_SceneFade → FeedbackFadeIn (淡入:画面显现)
```
**配置步骤FeedbackFadeOut**
1. 选中 `FeedbackFadeOut` GameObject
2. 在 Inspector 中找到 `MMF Player` 组件,点击 **`+`** 添加 Feedback
3. 选择 `UI > Canvas Group Alpha`(推荐)或 `Rendering > PostProcessing`
4. 配置参数:
- **目标 CanvasGroup**:创建一个全屏黑色 Image 挂在 `SYS_SceneFade` 下,添加 `CanvasGroup`,将其拖入
- **Alpha From**`0`**Alpha To**`1`(淡出 = 变黑)
- **Duration**`0.35 s`(需 ≤ `SceneService._sceneFadeDuration`,默认 `0.4 s`
5. 配置 `FeedbackFadeIn`(镜像操作):
- **Alpha From**`1`**Alpha To**`0`(淡入 = 显现)
- Duration 同上
> **重要约束**
> MMF_Player 的总时长Duration**必须 ≤ `SceneService._sceneFadeDuration`(默认 0.4 s**
> 否则淡出动画尚未播完,场景已开始加载,视觉上会有闪烁。
> 如需更长的过渡,在 `SERVICES → SceneService` Inspector 中同步调大 `_sceneFadeDuration`。
**推荐全屏遮罩层级结构:**
```
SYS_SceneFade
├── ScreenOverlay ← Image全屏黑色+ CanvasGroupalpha 0
│ 需在此 Canvas 上设置 Sort Order 高于所有其他 UI Canvas
├── FeedbackFadeOut ← SceneFeedback + MMF_Playertarget: ScreenOverlay.CanvasGroup
└── FeedbackFadeIn ← SceneFeedback + MMF_Playertarget: ScreenOverlay.CanvasGroup
```
---
### 4.2 SplashScreenController美术资源替换
脚手架已创建 `StudioLogo``GameTitle` 子节点(带 `CanvasGroup`),默认为空。
| 子节点 | 需要添加 | 说明 |
|---|---|---|
| `StudioLogo` | `Image` 组件 + 工作室 Logo 贴图 | 设置 Preserve Aspect = true |
| `GameTitle` | `Image` 组件 + 游戏标题图 | 同上 |
时序参数(可在 `SplashScreenController` Inspector 中调整):
| 字段 | 默认值 | 说明 |
|---|---|---|
| `_fadeInDuration` | `0.8 s` | 每个 Logo 的淡入时长 |
| `_holdDuration` | `1.5 s` | 停留时长 |
| `_fadeOutDuration` | `0.6 s` | 淡出时长 |
| `_stageGapDuration` | `0.3 s` | 两段演出之间的间隔 |
---
### 4.3 LoadingScreenManager背景图与提示文字
脚手架已创建进度条 Image 和 TipText以下字段仍需手动填写
| 字段 | 类型 | 说明 |
|---|---|---|
| `_backgroundArts` | `Image[]` | 加载画面随机背景图数组,留空则无背景 |
| `_tipMessages` | `string[]` | 本地化 key 列表(对应 Localization `UI` 表),留空则不显示提示文字 |
| `_minDisplayTime` | `float`(默认 0.5 s | 加载极快时的最短显示时间,避免画面闪烁 |
**进度条设置确认:**
`ProgressBarFill` Image 已由脚手架设置为 `Image.Type = Filled``FillMethod = Horizontal`
确认 `Fill Origin = Left`,并将图片 Import Settings 的 `Wrap Mode` 设为 `Clamp`
---
### 4.4 HUDControllerUI 资源绑定
`HUDController` 依赖较多图标/文本/进度条 Prefab均需在 Inspector 手动绑定。
具体字段参见 `Assets/_Game/Scripts/UI/HUD/HUDController.cs` 中的 `[SerializeField]` 注释。
> HUD 资源较多,建议参考美术规范文档 `Docs/Design/UI_HUD_Spec.md`(如已存在)进行配置。
---
### 4.5 AudioManagerAudioMixer 指定
**节点:** `[SERVICES] → AudioManager`
| 字段 | 说明 |
|---|---|
| `_mixer` | 拖入 `Assets/_Game/Audio/MainMixer.mixer`(或对应的 AudioMixer 资产) |
| `_masterVolumeParam` | AudioMixer 中 Master 音量参数名(默认 `"MasterVolume"` |
| `_bgmVolumeParam` | BGM 音量参数名(默认 `"BGMVolume"` |
| `_sfxVolumeParam` | SFX 音量参数名(默认 `"SFXVolume"` |
脚手架已自动创建 2 个 BGM Source 和 6 个 SFX Source 并绑定。
---
### 4.6 PauseMenuController按钮文本与样式
脚手架已创建 4 个按钮子节点(`Btn_Resume` / `Btn_Settings` / `Btn_MainMenu` / `Btn_Quit`),但节点仅含 `Button` 组件,没有视觉内容。
每个按钮需要添加:
- `Image` 组件(或替换为 `TextMeshProUGUI` 子节点作为标签)
- 根据 UI 设计规范配置 Sprite / 颜色 / Navigation
---
## 5. 事件频道速查表
以下是 Persistent 场景相关的全部事件频道。
所有资产由 `BaseGames → Scene → Setup → Create All Event Channel Assets` 自动生成到 `Assets/_Game/Events/`
| SO 名称 | 类型 | 发布者 | 订阅者 |
|---|---|---|---|
| `EVT_FadeOutRequest` | VoidEventChannelSO | SceneService | SceneFadeController |
| `EVT_FadeInRequest` | VoidEventChannelSO | SceneService | SceneFadeController |
| `EVT_LoadingStarted` | VoidEventChannelSO | SceneService / SceneLoader | LoadingScreenManager |
| `EVT_LoadingComplete` | VoidEventChannelSO | SceneService / SceneLoader | LoadingScreenManager |
| `EVT_LoadingProgressUpdated` | FloatEventChannelSO | SceneLoader | LoadingScreenManager |
| `EVT_SplashStartRequest` | VoidEventChannelSO | BootSequencer | SplashScreenController |
| `EVT_SplashComplete` | VoidEventChannelSO | SplashScreenController | BootSequencer |
| `EVT_SceneLoadRequest` | SceneLoadRequestEventChannelSO | DoorTransition / RoomTransition / PauseMenuController | SceneService |
| `EVT_GameStateChanged` | GameStateEventChannelSO | GameManager | UIManager |
| `EVT_PauseRequested` | VoidEventChannelSO | InputHandler | UIManager |
| `EVT_DeathScreenConfirmed` | VoidEventChannelSO | DeathScreenController | DeathRespawnService |
| `EVT_ResumeRequested` | VoidEventChannelSO | PauseMenuController | GameManager |
---
## 6. 场景切换完整时序
```
玩家触碰门触发器
├─ DoorTransition.OnTriggerEnter2D()
│ └─ ServiceLocator<ISceneService>.Get().RequestTransition(request)
└─ SceneService.LoadSceneCoroutine()
├─ 1. EVT_FadeOutRequest.Raise()
│ └─ SceneFadeController → FeedbackFadeOut.Play()
│ └─ MMF_Player → 画面变黑(≤ 0.4 s
├─ 2. yield WaitForSeconds(_sceneFadeDuration) ← 等待黑幕完成
├─ 3. [可选] EVT_LoadingStarted.Raise()
│ └─ LoadingScreenManager.Show()
├─ 4. UnloadOldScene / LoadNewSceneAddressables
├─ 5. [可选] EVT_LoadingComplete.Raise()
│ └─ LoadingScreenManager.Hide()
└─ 6. EVT_FadeInRequest.Raise()
└─ SceneFadeController → FeedbackFadeIn.Play()
└─ MMF_Player → 画面显现(≤ 0.4 s
```
---
## 7. 常见问题排查
### Q运行后画面直接跳转没有淡入淡出效果
**原因:** `FeedbackFadeOut` / `FeedbackFadeIn``MMF_Player` 中没有添加任何 Feedback。
**解决:** 参见 [4.1 节](#41-scenefade配置-mmf_player-淡入淡出效果) 添加 `Canvas Group Alpha` Feedback。
---
### Q淡出动画播放到一半画面就跳转了
**原因:** `MMF_Player` 总时长超过了 `SceneService._sceneFadeDuration`(默认 0.4 s
**解决:** 缩短 MMF_Player 的 Duration或在 `SceneService` Inspector 中加大 `_sceneFadeDuration`
---
### Q脚手架运行后报告显示某事件频道未找到
**原因:** 事件频道资产尚未生成。
**解决:** 先执行 `BaseGames → Scene → Setup → Create All Event Channel Assets`,再重新运行 `Scaffold Persistent Scene`
---
### QUIManager 的 `_panels` 数组为空
**原因:** 可能在旧版本的 Persistent 场景上重新运行了脚手架(幂等逻辑生效,但 `_panels` 已存在数据)。
**解决:** 在 Inspector 中展开 `UIManager._panels`,确认 4 个条目Pause / Settings / Map / Shop及其 `root` 引用均正确指向对应的 GameObject。
---
### Q暂停菜单打开后按钮没有响应
**可能原因 1** `_onResumeRequested` 未绑定(脚手架未找到对应 SO。检查 `PauseMenuController` Inspector。
**可能原因 2** `EventSystem` 缺失。确认 Persistent 场景中存在 `EventSystem` GameObject脚手架会自动创建