【AI编码】补充文档
parent
7c4000b5c9
commit
15ef71cfe6
|
|
@ -0,0 +1,393 @@
|
|||
# 暂停状态下技能释放流程说明
|
||||
|
||||
> 本文档由 AI 生成,用于说明暂停状态下玩家主动释放技能的完整流程逻辑。
|
||||
|
||||
## 功能概述
|
||||
|
||||
在战斗暂停状态下,玩家可以为多个单位预先选择技能释放位置。这些技能会被**缓存**起来,等到**解除暂停**后统一释放执行。
|
||||
|
||||
**核心特点**:
|
||||
- 暂停时选择技能 → 缓存到字典
|
||||
- 解除暂停时 → 统一发送释放事件
|
||||
- 支持覆盖、取消已缓存的技能
|
||||
|
||||
---
|
||||
|
||||
## 核心类职责
|
||||
|
||||
| 类名 | 职责 |
|
||||
|------|------|
|
||||
| `SkillAreaSelector2` | 技能区域选择器,处理预览、选择、取消 |
|
||||
| `SkillPauseCacheManager` | 暂停时技能缓存管理器,存储已缓存的技能数据 |
|
||||
| `InPauseCacheSkillArea` | 显示已缓存技能的释放位置(特殊显示逻辑) |
|
||||
| `GroundPlaneManager` | 地面面片管理器,负责实际的地面显示 |
|
||||
| `CommonSkillAreaSelector` | 基类,处理暂停/恢复、事件注册 |
|
||||
| `FightSkillPutManager` | 技能释放UI管理器 |
|
||||
|
||||
---
|
||||
|
||||
## 技能释放类型枚举
|
||||
|
||||
**文件**:`Assets/Code/Scripts/GamePlay/Area/Skill/SkillAreaSelector2.cs`
|
||||
|
||||
```csharp
|
||||
public enum ECacheUseType
|
||||
{
|
||||
RealUse, // 非暂停时,真正释放
|
||||
CacheUse, // 暂停时,缓存技能
|
||||
Cancel, // 取消技能选择
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 完整流程
|
||||
|
||||
### 阶段1:进入技能预览
|
||||
|
||||
**入口方法**:`SkillAreaSelector2.EnterPreview(SkillHandle skill)`
|
||||
|
||||
```csharp
|
||||
public void EnterPreview(SkillHandle skill)
|
||||
{
|
||||
// 隐藏其他区域显示
|
||||
AreaManager.instance.moveAreaView.Hide();
|
||||
AreaManager.instance.investigateAreaView.Hide();
|
||||
AreaManager.instance.attackArea.HideArea();
|
||||
|
||||
skillHandle = skill;
|
||||
|
||||
// 通知UI打开界面
|
||||
FightSkillPutManager.Instance.EnterSkillPut(skill.owner);
|
||||
|
||||
// 暂停游戏(记录当前速度)
|
||||
_PauseGame();
|
||||
|
||||
// 计算技能范围、创建区域显示
|
||||
_CalcSkillCellIndex();
|
||||
_CreateSkillAreaBoard();
|
||||
|
||||
// 显示屏幕特效
|
||||
SkillManager.instance.screenEffect.Show();
|
||||
|
||||
// 预选格子和单位
|
||||
_PreSelectCellIndex();
|
||||
_PreSelectUnits();
|
||||
_AttachHighlights();
|
||||
|
||||
// 注册事件监听
|
||||
_RegisterEvents();
|
||||
}
|
||||
```
|
||||
|
||||
### 阶段2:确认技能释放
|
||||
|
||||
**方法**:`SkillAreaSelector2._OnEventClickCellIndex(int cellIndex)`
|
||||
|
||||
```csharp
|
||||
protected override void _OnEventClickCellIndex(int cellIndex)
|
||||
{
|
||||
if (!_preSelectCellIndexList.Contains(cellIndex))
|
||||
{
|
||||
UITipsManager.ShowTips("无法在此处释放技能", EShowTipType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
var cacheSkillHandle = skillHandle;
|
||||
|
||||
if (_oldTimeSpeed == 0) // 之前是暂停状态
|
||||
{
|
||||
// 取消选中
|
||||
LevelManager.Instance.CurrentLevel.UnSelectUnit();
|
||||
|
||||
// 暂停状态下不能释放技能, 改为暂存
|
||||
ExitPreview(ECacheUseType.CacheUse).Forget();
|
||||
|
||||
var eventData = new EventDataUseSkill()
|
||||
{
|
||||
sender = cacheSkillHandle.owner,
|
||||
pointCellIndex = cellIndex,
|
||||
};
|
||||
EventManager.Instance.Send(EventManager.EventName.UI_CACHE_SKILL, eventData);
|
||||
}
|
||||
else // 之前是运行状态
|
||||
{
|
||||
ExitPreview(ECacheUseType.RealUse).Forget();
|
||||
|
||||
var eventData = new EventDataUseSkill()
|
||||
{
|
||||
sender = cacheSkillHandle.owner,
|
||||
pointCellIndex = cellIndex,
|
||||
};
|
||||
EventManager.Instance.Send(EventManager.EventName.UI_USE_SKILL, eventData);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 阶段3:缓存技能
|
||||
|
||||
**文件**:`Assets/Code/Scripts/GamePlay/Level/SkillPauseCache/SkillPauseCacheManager.cs`
|
||||
|
||||
```csharp
|
||||
private void OnCacheSkill(EventDataUseSkill eventDataUseSkill)
|
||||
{
|
||||
// 使用字典索引器,相同key会自动覆盖
|
||||
dicCacheSkill[eventDataUseSkill.sender] = eventDataUseSkill;
|
||||
|
||||
// 设置目标格子
|
||||
eventDataUseSkill.sender.controlData.targetCellIndex = eventDataUseSkill.sender.transData.cellIndex;
|
||||
eventDataUseSkill.sender.controlData.moveTargetCellIndex = eventDataUseSkill.sender.transData.cellIndex;
|
||||
|
||||
// 触发对话事件
|
||||
if (EGameUnitType.Character == eventDataUseSkill.sender.gameunitType)
|
||||
DialogueManager.Instance.OnFightUseSkill(eventDataUseSkill.sender);
|
||||
}
|
||||
```
|
||||
|
||||
### 阶段4:解除暂停时释放
|
||||
|
||||
```csharp
|
||||
private void OnPauseStateChange()
|
||||
{
|
||||
if (ELevelSpeed.Level_0 == curLevel.GetSpeed())
|
||||
return;
|
||||
|
||||
// 遍历所有缓存的技能,发送释放事件
|
||||
foreach (EventDataUseSkill eventDataUseSkill in dicCacheSkill.Values)
|
||||
{
|
||||
EventManager.Instance.Send(EventManager.EventName.UI_USE_SKILL, eventDataUseSkill);
|
||||
}
|
||||
|
||||
// 清空缓存
|
||||
dicCacheSkill.Clear();
|
||||
|
||||
// 发送指挥官技能缓存事件
|
||||
EventManager.Instance.Send(EventManager.EventName.UseCacheCommanderSkill);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 特殊显示逻辑
|
||||
|
||||
### InPauseCacheSkillArea 类
|
||||
|
||||
**文件**:`Assets/Code/Scripts/GamePlay/Area/Skill/InPauseCacheSkillArea.cs`
|
||||
|
||||
**功能**:当玩家在暂停状态下选中一个已缓存技能的单位时,在地面上显示该单位技能将要释放的位置。
|
||||
|
||||
#### 事件监听
|
||||
|
||||
| 事件 | 处理方法 | 作用 |
|
||||
|------|---------|------|
|
||||
| `INFIGHT_PAUSE_CHANGED` | `_OnPauseChanged()` | 监听暂停状态变化 |
|
||||
| `LevelUnitSelect` | `_OnUnitSelected()` | 选中单位时尝试显示缓存技能区域 |
|
||||
| `LevelUnitUnSelect` | `_OnUnitUnSelected()` | 取消选中时隐藏显示 |
|
||||
|
||||
#### 显示流程
|
||||
|
||||
```csharp
|
||||
private void _ShowCachedSkillArea()
|
||||
{
|
||||
// 1. 清除旧的显示
|
||||
GroundPlaneManager.Instance.UnregisterPlanes(this);
|
||||
|
||||
if (_selectedUnit == null)
|
||||
return;
|
||||
|
||||
// 2. 获取单位的技能管理器
|
||||
var unitSkillManager = SkillManager.instance.GetUnitSkillManager(_selectedUnit);
|
||||
|
||||
// 3. 获取主动技能
|
||||
var skillHandle = unitSkillManager.positiveSkill;
|
||||
|
||||
// 4. 获取技能的显示区域ID
|
||||
var showAreaId = skillHandle.runtimeData.configData.ShowAreaId;
|
||||
|
||||
// 5. 查询缓存数据
|
||||
if (!SkillPauseCacheManager.Ins.TryGetChcheSkillData(_selectedUnit, out var skillData))
|
||||
{
|
||||
return; // 无缓存数据,不显示
|
||||
}
|
||||
|
||||
// 6. 计算技能影响的格子列表
|
||||
var getAreaCellIndexList = AreaManager.instance.GetCellIndexs(skillData.pointCellIndex, showAreaId);
|
||||
|
||||
// 7. 注册地面显示
|
||||
GroundPlaneManager.Instance.RegisterPlanes(
|
||||
getAreaCellIndexList,
|
||||
GroundPlaneType.InPauseCacheSkill, // 专用显示类型
|
||||
this
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### 显示资源
|
||||
|
||||
- **类型**:`GroundPlaneType.InPauseCacheSkill`
|
||||
- **Prefab**:`Assets/Art_Out/Other/SkillArea/skill_inpause_preview_point.prefab`
|
||||
|
||||
---
|
||||
|
||||
## 缓存技能的覆盖逻辑
|
||||
|
||||
当一个单位**已经缓存了技能**,玩家**再次为该单位选择技能释放位置**时,会直接**覆盖**之前的缓存数据。
|
||||
|
||||
### 覆盖机制
|
||||
|
||||
```csharp
|
||||
// 使用字典的索引器赋值,如果key已存在则覆盖
|
||||
dicCacheSkill[eventDataUseSkill.sender] = eventDataUseSkill;
|
||||
```
|
||||
|
||||
### 覆盖流程示例
|
||||
|
||||
| 步骤 | 操作 | dicCacheSkill 状态 |
|
||||
|------|------|-------------------|
|
||||
| 1 | 为单位A选择释放点(格子100) | `{ A → 格子100 }` |
|
||||
| 2 | 再次为单位A选择释放点(格子200) | `{ A → 格子200 }` (覆盖) |
|
||||
| 3 | 解除暂停 | 技能释放到格子200 |
|
||||
|
||||
### 设计特点
|
||||
|
||||
| 特点 | 说明 |
|
||||
|------|------|
|
||||
| **自动覆盖** | 使用字典索引器,相同key自动覆盖 |
|
||||
| **无确认提示** | 覆盖时不会提示玩家 |
|
||||
| **每单位一个缓存** | 字典以 `GameUnit` 为key,每个单位最多只能缓存一个技能释放数据 |
|
||||
| **对话重新触发** | 覆盖时会再次调用 `DialogueManager.OnFightUseSkill` |
|
||||
|
||||
---
|
||||
|
||||
## 取消缓存技能的方式
|
||||
|
||||
| 方式 | 触发条件 | 处理逻辑 |
|
||||
|------|---------|---------|
|
||||
| **移动指令取消** | 给单位下达移动指令 | `INFIGHT_AUDIO_CLICK_MOVE` 事件 → `OnClearSkillCache()` → `dicCacheSkill.Remove(unit)` |
|
||||
| **解除暂停释放** | 游戏恢复运行 | 遍历缓存发送 `UI_USE_SKILL` → 清空缓存 |
|
||||
| **取消技能选择** | 点击取消按钮 | `ExitPreview(Cancel)` → 退出预览,不修改已有缓存 |
|
||||
|
||||
### 移动指令取消
|
||||
|
||||
**文件**:`Assets/Code/Scripts/GamePlay/AI/AIManager.Directive.cs`
|
||||
|
||||
```csharp
|
||||
if (isPlayerOperate && unit is UnitCharacter character)
|
||||
{
|
||||
EventManager.Instance.Send(EventManager.EventName.INFIGHT_AUDIO_CLICK_MOVE, character);
|
||||
}
|
||||
```
|
||||
|
||||
**文件**:`Assets/Code/Scripts/GamePlay/Level/SkillPauseCache/SkillPauseCacheManager.cs`
|
||||
|
||||
```csharp
|
||||
private void OnClearSkillCache(GameUnit gameUnit)
|
||||
{
|
||||
dicCacheSkill.Remove(gameUnit);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 关键事件
|
||||
|
||||
| 事件名 | 触发时机 | 处理者 | 结果 |
|
||||
|--------|---------|--------|------|
|
||||
| `UI_CACHE_SKILL` | 暂停时确认技能释放点 | `SkillPauseCacheManager` | 缓存技能数据 |
|
||||
| `UI_USE_SKILL` | 非暂停时选择 / 解除暂停时 | `SkillManager` | 真正释放技能 |
|
||||
| `INFIGHT_UI_CANCEL_USE_SKILL` | 点击取消按钮 | `SkillAreaSelector2` | 退出技能预览 |
|
||||
| `INFIGHT_AUDIO_CLICK_MOVE` | 玩家操作单位移动 | `SkillPauseCacheManager` | 清除该单位的缓存技能 |
|
||||
| `LevelFightUIPauseChange` | 暂停状态变化 | `SkillPauseCacheManager` | 解除暂停时释放所有缓存 |
|
||||
| `LevelSpeedChange` | 游戏速度变化 | `SkillPauseCacheManager` | 解除暂停时释放所有缓存 |
|
||||
| `LevelUnitSelect` | 选中单位 | `InPauseCacheSkillArea` | 显示该单位的缓存技能区域 |
|
||||
| `LevelUnitUnSelect` | 取消选中 | `InPauseCacheSkillArea` | 隐藏缓存技能区域显示 |
|
||||
| `INFIGHT_PAUSE_CHANGED` | 暂停状态变化 | `InPauseCacheSkillArea` | 解除暂停时隐藏显示 |
|
||||
|
||||
---
|
||||
|
||||
## 关键数据结构
|
||||
|
||||
### SkillPauseCacheManager.dicCacheSkill
|
||||
|
||||
```csharp
|
||||
Dictionary<GameUnit, EventDataUseSkill> dicCacheSkill;
|
||||
```
|
||||
|
||||
### EventDataUseSkill
|
||||
|
||||
```csharp
|
||||
public class EventDataUseSkill
|
||||
{
|
||||
public GameUnit sender; // 释放技能的单位
|
||||
public int pointCellIndex; // 技能释放的目标格子
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 流程总结图
|
||||
|
||||
```
|
||||
玩家操作 系统响应
|
||||
─────────────────────────────────────────────────────────────────────
|
||||
|
||||
① 暂停状态下点击角色技能 → 进入技能预览
|
||||
├─ 暂停游戏
|
||||
├─ 显示技能范围
|
||||
└─ 等待玩家选择
|
||||
|
||||
② 选择释放位置并确认 → 缓存技能 + 取消选中
|
||||
├─ dicCacheSkill[unit] = data
|
||||
└─ UnSelectUnit()
|
||||
|
||||
③ 再次点击该单位 → 显示缓存技能区域
|
||||
└─ GroundPlaneManager 显示
|
||||
skill_inpause_preview_point
|
||||
|
||||
④ 点击其他单位/取消选中 → 隐藏缓存技能区域
|
||||
└─ GroundPlaneManager 隐藏
|
||||
|
||||
⑤ 再次为该单位选择技能 → 覆盖缓存技能
|
||||
└─ dicCacheSkill[unit] = newData
|
||||
|
||||
⑥ 给该单位下达移动指令 → 取消该单位的缓存技能
|
||||
└─ dicCacheSkill.Remove(unit)
|
||||
|
||||
⑦ 解除暂停 → 释放所有缓存技能
|
||||
├─ 遍历发送 UI_USE_SKILL
|
||||
├─ 清空 dicCacheSkill
|
||||
└─ 隐藏所有缓存区域显示
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 相关代码文件
|
||||
|
||||
| 文件路径 | 说明 |
|
||||
|---------|------|
|
||||
| `Assets/Code/Scripts/GamePlay/Area/Skill/SkillAreaSelector2.cs` | 技能区域选择器 |
|
||||
| `Assets/Code/Scripts/GamePlay/Area/Skill/CommonSkillAreaSelector.cs` | 技能区域选择器基类 |
|
||||
| `Assets/Code/Scripts/GamePlay/Area/Skill/InPauseCacheSkillArea.cs` | 暂停状态缓存技能区域显示 |
|
||||
| `Assets/Code/Scripts/GamePlay/Level/SkillPauseCache/SkillPauseCacheManager.cs` | 技能暂停缓存管理器 |
|
||||
| `Assets/Code/Scripts/GamePlay/Skill/SkillManager.cs` | 技能管理器 |
|
||||
| `Assets/Code/Scripts/GamePlay/Skill/FightSkillPutManager.cs` | 技能释放UI管理器 |
|
||||
| `Assets/Code/Scripts/GamePlay/UI/LevelFight/FightSceneUI/UISkillPutController.cs` | 技能释放UI控制器 |
|
||||
| `Assets/Code/Scripts/GamePlay/GroundPlane/GroundPlaneManager.cs` | 地面面片管理器 |
|
||||
| `Assets/Code/Scripts/GamePlay/GroundPlane/GroundPlaneType.cs` | 地面面片类型枚举 |
|
||||
| `Assets/Code/Scripts/GamePlay/Common/PathDefine.cs` | 路径定义(包含预制体路径) |
|
||||
| `Assets/Code/Scripts/GamePlay/AI/AIManager.Directive.cs` | AI指令管理(移动指令触发取消缓存) |
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **显示时机**:只有在暂停状态下选中已缓存技能的单位时才会显示缓存区域
|
||||
2. **自动隐藏**:解除暂停时会自动隐藏所有缓存区域显示
|
||||
3. **资源预加载**:`skill_inpause_preview_point.prefab` 在关卡加载时预加载
|
||||
4. **每单位限制**:每个单位最多只能缓存一个技能,再次选择会覆盖
|
||||
5. **取消选中**:确认技能释放点后会自动取消选中该单位,方便玩家继续操作其他单位
|
||||
|
||||
---
|
||||
|
||||
*文档生成时间:2026-02-05*
|
||||
*生成工具:Cursor AI Agent*
|
||||
Loading…
Reference in New Issue