1277 lines
70 KiB
Markdown
1277 lines
70 KiB
Markdown
# 横版 3D 格斗小游戏开发设计文档
|
||
|
||
**2.5D · 1v1 · 帧数据驱动 · 单机原型基线**
|
||
|
||
| **版本** | v1.0 |
|
||
|--------------|------------------------------------|
|
||
| **日期** | 2026-08-10 |
|
||
| **技术基线** | 引擎无关;示例采用 Unity / C# 命名 |
|
||
|
||
> 目标:用最小但正确的战斗架构,实现行走、跳跃、格挡、拳脚、必杀技、超必杀技、命中反馈与完整回合流程;同时为后续角色扩展、训练模式和回滚联机保留清晰边界。
|
||
|
||
| **核心战斗** | **数据驱动** | **可验证** |
|
||
| --- | --- | --- |
|
||
| 输入缓冲 · 状态机 · 命中结算 | 招式帧表 · 判定轨迹 · 资源规则 | 帧步进 · Hitbox 调试 · 验收用例 |
|
||
|
||
**DOCUMENT CONTROL**
|
||
|
||
# 文档控制与阅读说明
|
||
|
||
本文档是面向小型团队或个人开发者的可执行设计基线。它同时覆盖玩法规则、核心战斗技术方案、数据结构、调试工具、开发计划与验收标准。所有数值均为首轮灰盒原型建议值,应通过手感测试迭代。
|
||
|
||
| **字段** | **内容** |
|
||
|------------------|----------------------------------------------------|
|
||
| **项目类型** | 横版 3D(2.5D)1v1 对战格斗小游戏 |
|
||
| **首发平台** | PC;键盘与手柄;本地双人或玩家对 AI |
|
||
| **画面实现** | 3D 角色与场景,战斗逻辑约束在水平轴与垂直轴 |
|
||
| **战斗基线** | 固定 60 Tick;帧数据驱动;运动学角色控制器 |
|
||
| **参考代码风格** | Unity / C# 命名;可映射至 Unreal、Godot 或自研引擎 |
|
||
| **目标读者** | 程序、策划、动画、特效、测试与制作人 |
|
||
|
||
> **关键边界**
|
||
>
|
||
> MVP 不做联网、投技、复杂防御资源、角色养成与剧情。先确保“输入可靠、状态可控、命中可解释、帧数据可调”,再增加内容。
|
||
|
||
## 术语约定
|
||
|
||
| **术语** | **定义** |
|
||
|--------------------------------|-------------------------------------------------------------------------------|
|
||
| **战斗 Tick** | 战斗逻辑更新单位;固定为每秒 60 次,与渲染帧率解耦。 |
|
||
| **起手 / 持续 / 收招** | Startup / Active / Recovery;攻击从输入到判定生效,再到恢复可行动的三个阶段。 |
|
||
| **HitStop** | 命中瞬间双方短暂停顿,用于强化重量感;不等同于受击硬直。 |
|
||
| **HitStun / BlockStun** | 命中硬直 / 格挡硬直;期间角色不能自由行动,但可受特定规则影响。 |
|
||
| **HitBox / HurtBox / PushBox** | 攻击判定 / 可受击判定 / 角色实体推挤判定。 |
|
||
| **取消窗口** | 允许当前动作提前转入指定动作的帧区间。 |
|
||
| **指令宽容** | 方向输入允许的总时间、相邻输入最大间隔、斜方向替代等容错规则。 |
|
||
|
||
## 目录
|
||
|
||
| **01 项目定位与设计目标** | **11 动画、特效、音效与镜头** |
|
||
|-----------------------------|-------------------------------|
|
||
| 02 MVP 范围与内容规格 | 12 技术架构与更新顺序 |
|
||
| 03 比赛规则与战斗空间 | 13 数据配置与资源规范 |
|
||
| 04 输入、缓冲与指令识别 | 14 UI、回合流程与设置 |
|
||
| 05 角色状态机与转移优先级 | 15 AI 与训练木桩 |
|
||
| **06 行走、跳跃与角色运动** | **16 性能、回放与联机预留** |
|
||
| 07 拳脚攻击与招式时间轴 | 17 调试工具与可观测性 |
|
||
| 08 格挡、防御与受击规则 | 18 开发里程碑与任务拆分 |
|
||
| 09 HitBox 与命中结算管线 | 19 测试方案与验收标准 |
|
||
| 10 必杀技、超必杀技与能量 | 20 风险、原创边界与附录 |
|
||
|
||
**PRODUCT VISION**
|
||
|
||
# 01 项目定位与设计目标
|
||
|
||
本项目是一款使用 3D 角色和场景、但将对战规则限制在二维战斗平面的 1v1 格斗小游戏。玩家通过走位、跳跃、格挡、拳脚、必杀技与超必杀技争夺回合胜利。重点不是堆叠招式数量,而是建立清晰、稳定、可调试的战斗内核。
|
||
|
||
## 1.1 玩家体验目标
|
||
|
||
- 输入响应明确:按键、方向与指令不会因为渲染帧率或动画事件而随机失效。
|
||
|
||
- 攻防结果可理解:为什么命中、为什么被格挡、为什么发生交易命中,都能通过调试数据解释。
|
||
|
||
- 打击有重量:命中停顿、受击动作、音效、火花、震屏与击退在同一事件上同步。
|
||
|
||
- 学习成本可控:MVP 只提供少量高辨识度招式,先形成“近身、对空、飞行道具、爆发技”的完整循环。
|
||
|
||
- 内容可扩展:新增角色主要通过配置数据、动画和判定轨迹完成,避免复制并修改大量角色逻辑。
|
||
|
||
## 1.2 核心循环
|
||
|
||
| **阶段** | **玩家行为** | **系统反馈** |
|
||
|-----------------|------------------------------|--------------------------------|
|
||
| **中立博弈** | 前后移动、试探、跳跃、预判 | 距离、站位、能量与时间形成压力 |
|
||
| **进攻确认** | 拳脚命中或迫使对手格挡 | HitStop、硬直、推远、命中特效 |
|
||
| **连段 / 取消** | 用轻攻击确认,再取消到必杀技 | 连击数、伤害缩放、资源增长 |
|
||
| **防守反击** | 格挡、后退、等待收招空隙 | 格挡硬直、削血、反击提示 |
|
||
| **资源爆发** | 积满能量后使用超必杀技 | 屏幕冻结、镜头强化、多段命中 |
|
||
| **回合结算** | KO 或时间结束 | 慢镜、胜负 UI、重开或下一回合 |
|
||
|
||
## 1.3 设计原则
|
||
|
||
> **1.** 战斗逻辑先于表现:战斗结果由数据与状态决定,动画、特效和镜头只消费结果。
|
||
>
|
||
> **2.** 整数帧优先:所有招式时序、无敌、取消与硬直均用战斗 Tick 表达。
|
||
>
|
||
> **3.** 单一结算入口:所有近战、飞行道具和超必杀命中都进入同一 HitResolver。
|
||
>
|
||
> **4.** 配置优先于分支:角色差异放入 CharacterData、MoveData 与 HitboxTrack,而不是散落在代码中的 if/else。
|
||
>
|
||
> **5.** 调试能力属于产品功能:从第一周就提供帧步进、输入历史和判定框显示。
|
||
|
||
> **成功标准**
|
||
>
|
||
> 两个相同灰盒角色也能玩出完整回合:走位可控、跳跃轨迹稳定、拳脚可命中/格挡、必杀与超杀可识别、KO 能结算;全流程无随机漏判和状态卡死。
|
||
|
||
**SCOPE**
|
||
|
||
# 02 MVP 范围与内容规格
|
||
|
||
## 2.1 首个可玩版本
|
||
|
||
| **优先级** | **功能** | **MVP 规格** |
|
||
|--------------|----------|----------------------------------------------------------|
|
||
| **P0 必须** | 角色移动 | 前走、后走、转身、蹲下、前跳、后跳、垂直跳、落地硬直 |
|
||
| **P0 必须** | 基础攻击 | 站立轻拳/重拳/轻脚/重脚,蹲轻脚,跳攻击;至少 6 个普通技 |
|
||
| **P0 必须** | 防御 | 按住背向方向格挡;站防、蹲防;格挡硬直、推远与削血规则 |
|
||
| **P0 必须** | 命中 | HitBox/HurtBox、HitStop、HitStun、击退、浮空、击倒、KO |
|
||
| **P0 必须** | 特殊招式 | 每角色 3 个必杀技:飞行道具、对空技、突进技 |
|
||
| **P0 必须** | 爆发资源 | 0–100 超必杀能量;每角色 1 个超必杀技 |
|
||
| **P0 必须** | 比赛流程 | 倒计时、生命、能量、局数、KO、时间结束、重开 |
|
||
| **P1 建议** | 对战对象 | 本地双人 + 简单 AI;训练木桩 |
|
||
| **P1 建议** | 调试 | 输入历史、帧计数、判定框、命中日志、帧步进 |
|
||
| **暂不实现** | 复杂系统 | 投技、拆投、空防、弹反、防御槽、角色养成、联网匹配 |
|
||
|
||
## 2.2 内容量建议
|
||
|
||
| **内容项** | **原型下限** | **首个完整 Demo** |
|
||
|--------------|------------------|---------------------------|
|
||
| **角色** | 1 个角色镜像对战 | 2 个原创角色 |
|
||
| **场景** | 1 个灰盒场景 | 1 个完整场景 + 1 个训练场 |
|
||
| **普通技** | 每角色 6 个 | 每角色 10–12 个 |
|
||
| **必杀技** | 每角色 2 个 | 每角色 3 个 |
|
||
| **超必杀技** | 每角色 1 个 | 每角色 1 个 |
|
||
| **AI 难度** | 1 档 | 3 档 |
|
||
| **回合规则** | 一局定胜负 | 三局两胜、99 秒 |
|
||
|
||
> **范围控制建议**
|
||
>
|
||
> 先用胶囊体、基础动作和纯色特效完成“第一可玩”;在手感通过前,不投入角色建模、复杂镜头和大量动作。任何新增功能都必须说明它改善了哪一种攻防决策。
|
||
|
||
## 2.3 非功能目标
|
||
|
||
- 标准 PC 在 1080p 下稳定 60 FPS;战斗 Tick 永远保持 60 Hz。
|
||
|
||
- 单次对战可从输入流重放,重放结果在同版本、同平台上保持一致。
|
||
|
||
- 角色招式数据修改后无需改核心代码即可生效。
|
||
|
||
- 战斗关键路径不产生持续 GC;飞行道具、命中特效和飘字使用对象池。
|
||
|
||
- 控制支持手柄与键盘重绑定,并提供震屏、闪光强度与输入显示开关。
|
||
|
||
**RULES & SPACE**
|
||
|
||
# 03 比赛规则与战斗空间
|
||
|
||
## 3.1 默认比赛规则
|
||
|
||
| **参数** | **默认值** | **说明** |
|
||
|----------------|------------------|------------------------------------|
|
||
| **局制** | 三局两胜 | 原型阶段可切换为一局定胜负 |
|
||
| **回合时间** | 99 秒 | 使用战斗时间;暂停与回合演出不计时 |
|
||
| **最大生命** | 1000 | 便于用整数表达伤害与缩放 |
|
||
| **超必杀能量** | 0–100 | 命中、格挡与受击均可按招式配置增长 |
|
||
| **时间结束** | 生命百分比高者胜 | 相同则判平局并重开该回合 |
|
||
| **KO 判定** | 生命值 ≤ 0 | 本 Tick 结算完成后进入 KO 状态 |
|
||
|
||
## 3.2 坐标系与战斗平面
|
||
|
||
建议将 X 轴定义为左右移动,Y 轴定义为高度,Z 轴为场景深度。角色逻辑位置始终投影到固定的战斗平面 Z = 0;3D 模型可在表现层有轻微深度偏移,但 PushBox、HurtBox 与 HitBox 均在同一逻辑平面计算。
|
||
|
||
- 舞台边界:X ∈ \[−StageHalfWidth, +StageHalfWidth\],角色中心不可越界。
|
||
|
||
- PushBox:两个角色不可穿透;先求期望位移,再按质量和边界分摊重叠量。
|
||
|
||
- 面对方向:每个 Tick 末根据双方 X 位置决定;攻击不可转身的帧区间保持原朝向。
|
||
|
||
- 交叉攻击:双方交换位置后,下一 Tick 更新面对方向;当前 Tick 的方向输入按 Tick 开始时朝向解释。
|
||
|
||
- 镜头:始终看向两人中点,并用距离和舞台边界控制缩放与平移。
|
||
|
||
## 3.3 战斗时间模型
|
||
|
||
> **固定战斗 Tick**
|
||
>
|
||
> 渲染可以是 60、120 或更高 FPS,但输入采样、状态推进、移动、碰撞与命中结算都以固定 1/60 秒为单位。动画播放速度由当前招式帧映射,不反过来驱动战斗结果。
|
||
|
||
| **时间域** | **是否受 HitStop 影响** | **典型内容** |
|
||
|----------------------|-------------------------|---------------------------------------|
|
||
| **BattleTime** | 是 | 招式帧、移动、飞行道具、受击/格挡硬直 |
|
||
| **PresentationTime** | 可选 | 粒子、镜头震动、音效尾音、UI 动画 |
|
||
| **RealTime** | 否 | 暂停菜单、设备重连、加载与调试界面 |
|
||
|
||
**INPUT**
|
||
|
||
# 04 输入、缓冲与指令识别
|
||
|
||
## 4.1 默认操作映射
|
||
|
||
| **动作** | **键盘示例** | **手柄示例** | **规则** |
|
||
|-------------|---------------|-----------------|------------------------------------|
|
||
| **方向** | WASD / 方向键 | 十字键 / 左摇杆 | 8 方向归一化;按角色朝向转换为前后 |
|
||
| **轻拳 LP** | J | X / □ | 快速、短距离、低伤害 |
|
||
| **重拳 HP** | K | Y / △ | 较慢、高伤害、可对空 |
|
||
| **轻脚 LK** | U | A / × | 中短距离、可做低段 |
|
||
| **重脚 HK** | I | B / ○ | 长距离、较大收招 |
|
||
| **暂停** | Esc | Menu / Options | 仅比赛允许时打开 |
|
||
|
||
*格挡默认不占独立按键:按住“远离对手”的方向进入格挡意图。可在辅助模式中增加 Guard 键。*
|
||
|
||
## 4.2 输入帧结构
|
||
|
||
每个渲染帧读取设备输入,将结果写入 InputBuffer;每个战斗 Tick 消费一个归一化输入快照。缓冲区建议保存最近 30–45 Tick,用于指令识别、输入显示、回放与问题复现。
|
||
|
||
| **字段** | **类型** | **用途** |
|
||
|--------------------|--------------|------------------------------------------|
|
||
| **Tick** | int | 输入发生的战斗 Tick |
|
||
| **Direction** | enum 1–9 | 数字小键盘方向;5 为中立 |
|
||
| **PressedMask** | bitmask | 本 Tick 新按下的攻击键 |
|
||
| **HeldMask** | bitmask | 本 Tick 持续按住的攻击键 |
|
||
| **ReleasedMask** | bitmask | 本 Tick 释放的攻击键;可用于负边输入扩展 |
|
||
| **FacingSnapshot** | Left / Right | 用于将世界方向转换为相对方向 |
|
||
| **ConsumedFlags** | bitmask | 避免同一次按键被多个动作重复消费 |
|
||
|
||
## 4.3 指令识别规则
|
||
|
||
- 方向按“相对朝向”解释:6 始终代表前,4 始终代表后。
|
||
|
||
- 从攻击键按下 Tick 向前回溯方向序列,而不是从最早输入向后搜索。
|
||
|
||
- 每条指令配置总窗口、相邻步骤最大间隔、是否允许斜方向替代、是否允许跳过中立。
|
||
|
||
- 同 Tick 多条指令成立时,按“超必杀 \> 必杀技 \> 特殊普通技 \> 普通技”排序。
|
||
|
||
- 动作进入后消费相关按键与方向片段,避免一个输入同时触发两个动作。
|
||
|
||
- 推荐首版宽容:必杀总窗口 12–16 Tick,超必杀 20–24 Tick,按键缓冲 4–6 Tick。
|
||
|
||
| **招式类型** | **输入示例** | **匹配序列** | **宽容建议** |
|
||
|--------------|-----------------|--------------|-------------------------------------|
|
||
| **飞行道具** | ↓ ↘ → + P | 2, 3, 6 + P | 允许 2,6 或 2,3,6;总窗口 14 Tick |
|
||
| **对空技** | → ↓ ↘ + P | 6, 2, 3 + P | 允许首个 6 来自前走;总窗口 12 Tick |
|
||
| **突进技** | ↓ ↙ ← + K | 2, 1, 4 + K | 斜方向必须出现;总窗口 14 Tick |
|
||
| **超必杀** | ↓ ↘ → ↓ ↘ → + P | 236236 + P | 总窗口 24 Tick;能量必须为 100 |
|
||
|
||
**指令识别伪代码(方向相对角色朝向)**
|
||
|
||
```csharp
|
||
bool TryMatch(Command cmd, InputBuffer buffer, int nowTick, Facing facing) {
|
||
int cursor = nowTick;
|
||
for (int i = cmd.steps.Count - 1; i >= 0; --i) {
|
||
cursor = buffer.FindPreviousMatch(
|
||
cmd.steps[i], cursor, cmd.maxGapTicks, facing);
|
||
if (cursor < 0) return false;
|
||
}
|
||
return nowTick - cursor <= cmd.totalWindowTicks
|
||
&& buffer.HasButtonPress(cmd.buttonMask, nowTick, cmd.buttonBufferTicks);
|
||
}
|
||
```
|
||
|
||
> **输入可靠性验收**
|
||
>
|
||
> 在固定录制的 1000 组输入序列中,识别结果必须完全一致;切换渲染帧率、开启慢动作或发生 HitStop 时,不得改变指令成立结果。
|
||
|
||
**STATE MACHINE**
|
||
|
||
# 05 角色状态机与转移优先级
|
||
|
||
角色使用分层状态机:顶层区分 Ground、Air、Attack、Reaction、Down 与 KO,子状态负责行走、跳跃、攻击阶段和受击类型。状态机只处理“角色当前允许做什么”,招式帧表负责“某个动作在第几帧发生什么”。
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
subgraph A["自然动作链"]
|
||
G["Ground<br/>Idle / Walk / Crouch / Turn"] -->|跳跃输入| JS["JumpStart"]
|
||
JS -->|起跳完成| AIR["Air<br/>Jump / Fall"]
|
||
AIR -->|接地| LAND["Landing"]
|
||
LAND -->|落地硬直结束| G
|
||
end
|
||
|
||
subgraph B["主动与防御分支"]
|
||
READY["Ground / Air<br/>当前可行动"] -->|攻击输入| ATK["Attack<br/>普通技 / 空中攻击"]
|
||
READY -->|指令成立| SP["Special / Super<br/>指令技 / 资源技"]
|
||
READY -->|有效格挡姿态| BLK["Block / BlockStun<br/>格挡意图 / 格挡硬直"]
|
||
ATK -->|动作结束| BACK["返回 Ground / Air"]
|
||
SP -->|动作结束| BACK
|
||
BLK -->|硬直结束| BACK
|
||
end
|
||
|
||
subgraph C["强制中断链(优先级高于普通输入)"]
|
||
NONKO["任意非 KO 状态"] -->|合法命中| HIT["HitStun / Launch<br/>站立受击 / 浮空"]
|
||
HIT -->|击倒| DOWN["Knockdown / Wakeup<br/>倒地 / 起身"]
|
||
DOWN -->|站立恢复或起身完成| GROUND["Ground"]
|
||
NONKO -->|生命归零| KO["KO / RoundEnd"]
|
||
HIT -->|受击阶段生命归零| KO
|
||
end
|
||
```
|
||
|
||
图 1 角色核心状态与主要转移
|
||
|
||
## 5.1 状态清单
|
||
|
||
| **状态组** | **子状态** | **关键职责** |
|
||
|--------------|-----------------------------------------------|----------------------------------------------------|
|
||
| **Ground** | Idle / Walk / Crouch / Turn | 读取移动与攻击输入;处理面对方向与地面摩擦 |
|
||
| **Air** | JumpStart / Jump / Fall / AirAttack / Landing | 处理起跳锁定、空中速度、接地与落地硬直 |
|
||
| **Attack** | Startup / Active / Recovery | 推进 MoveTimeline;开放 HitBox、取消窗口与位移曲线 |
|
||
| **Special** | Special / Super / Cinematic | 资源校验、无敌、飞行道具、屏幕冻结和多段命中 |
|
||
| **Defense** | Block / BlockStun | 格挡姿态、高低段校验、格挡硬直与推远 |
|
||
| **Reaction** | HitStun / Launch / WallBounce | 受击、浮空、击退、连段计数与恢复 |
|
||
| **Down** | Knockdown / Wakeup | 倒地时间、起身无敌与恢复站立 |
|
||
| **Terminal** | KO / RoundEnd | 禁用输入,播放结算动作与回合流程 |
|
||
|
||
## 5.2 转移优先级
|
||
|
||
同一 Tick 可能同时出现 KO、受击、落地、取消与新输入。为避免结果依赖代码调用顺序,所有转移先生成 TransitionRequest,再由统一优先级选择。建议顺序如下:
|
||
|
||
> **1.** KO / RoundEnd:生命归零或回合结束,覆盖所有普通转移。
|
||
>
|
||
> **2.** 强制受击:命中、击倒、浮空;无敌或装甲可在 HitResolver 阶段拦截。
|
||
>
|
||
> **3.** 脚本强制状态:超必杀演出、抓取演出(未来)、出生与回合开场。
|
||
>
|
||
> **4.** 取消转移:命中取消、格挡取消、特殊取消、超必杀取消。
|
||
>
|
||
> **5.** 接地 / 离地:落地、起跳帧结束、被击飞离地。
|
||
>
|
||
> **6.** 自然结束:收招、硬直、起身、转身结束。
|
||
>
|
||
> **7.** 玩家输入:走、蹲、跳、普通攻击、必杀技。
|
||
|
||
## 5.3 状态接口
|
||
|
||
**状态机接口建议**
|
||
|
||
```csharp
|
||
interface IFighterState {
|
||
void Enter(FighterContext ctx, StateEnterArgs args);
|
||
void PreTick(FighterContext ctx, in InputFrame input);
|
||
void Tick(FighterContext ctx); // 推进逻辑帧,不直接播放特效
|
||
void PostTick(FighterContext ctx); // 生成转移请求与表现事件
|
||
void Exit(FighterContext ctx);
|
||
}
|
||
|
||
struct TransitionRequest {
|
||
FighterStateId target;
|
||
int priority;
|
||
TransitionReason reason;
|
||
object payload;
|
||
}
|
||
```
|
||
|
||
> **避免的实现**
|
||
>
|
||
> 不要让 Animator StateMachineBehaviour 直接修改生命、开启判定或决定状态转移。动画事件可能因过渡、掉帧、速度变化或跳帧而漏发;它们最多用于非关键音效与装饰。
|
||
|
||
**MOVEMENT**
|
||
|
||
# 06 行走、跳跃与角色运动
|
||
|
||
## 6.1 运动学角色控制器
|
||
|
||
角色移动使用自定义 Kinematic FighterMotor,而不是依赖动态刚体。每个 Tick 计算期望速度与位移,执行舞台边界、地面检测和 PushBox 修正,再写回逻辑位置。这样能获得稳定、可重放且便于联网预留的结果。
|
||
|
||
| **参数** | **原型建议值** | **说明** |
|
||
|------------------|----------------|----------------------------------------|
|
||
| **前走速度** | 4.2 m/s | 接近对手时略快,鼓励主动走位 |
|
||
| **后走速度** | 3.4 m/s | 后退不应成为无成本脱离手段 |
|
||
| **蹲姿移动** | 0 m/s | MVP 中蹲下固定;后续可增加缓慢移动 |
|
||
| **跳跃初速度** | 8.5 m/s | 通过重力与初速度共同调整弧线 |
|
||
| **重力** | −28 m/s² | 建议自定义重力,不使用项目全局物理重力 |
|
||
| **空中水平速度** | 3.2 m/s | 起跳时锁定方向,允许少量空中修正可配置 |
|
||
| **落地硬直** | 4 Tick | 普通跳落地;空中攻击可配置更长硬直 |
|
||
| **PushBox 宽度** | 0.75 m | 站立基线;蹲姿可略小 |
|
||
|
||
*上述数值只用于灰盒验证;最终手感应以画面比例、角色身高和攻击距离统一调整。*
|
||
|
||
## 6.2 行走规则
|
||
|
||
- 方向输入为 6 时使用前走速度,4 时使用后走速度;“前/后”按角色面对方向解释。
|
||
|
||
- 攻击、格挡硬直、受击、倒地和大多数必杀技期间不读取普通行走输入。
|
||
|
||
- 进入 Turn 状态时可锁定 1–2 Tick,防止模型瞬间镜像造成脚步穿帮;逻辑朝向仍在规则允许时更新。
|
||
|
||
- 两个 PushBox 重叠时,先尝试各自退让一半;一方贴舞台边界时由另一方承担剩余位移。
|
||
|
||
- 不得用 CharacterController 的自动 StepOffset 造成 Z 轴或高度漂移;地面只允许设计好的坡度或平面。
|
||
|
||
## 6.3 跳跃规则
|
||
|
||
- 跳跃分为 JumpStart、Airborne、Landing。JumpStart 建议 3–4 Tick,期间可被命中。
|
||
|
||
- 起跳方向在 JumpStart 结束时锁定;垂直跳 X 速度为 0,前后跳使用各自速度。
|
||
|
||
- 空中不允许再次跳跃;是否允许空中格挡、空中必杀应由角色与招式数据显式配置。
|
||
|
||
- 接地判定使用脚底 Probe 与上一 Tick 高度,避免高速下落穿透地面。
|
||
|
||
- 被击飞时使用 ReactionVelocity,不复用普通跳跃状态,以便独立控制重力、弹地和受身。
|
||
|
||
**角色运动 Tick 伪代码**
|
||
|
||
```csharp
|
||
void SimulateMotor(Fighter f) {
|
||
Vec2 desired = f.State.BuildVelocity();
|
||
Vec2 delta = desired * BattleClock.FixedDelta;
|
||
delta = Stage.ClampToBounds(f.Position, delta, f.PushBox);
|
||
f.Position += delta;
|
||
PushSolver.ResolvePair(f, f.Opponent);
|
||
GroundProbe.ResolveLanding(f);
|
||
}
|
||
```
|
||
|
||
> **手感调试顺序**
|
||
>
|
||
> 先固定角色身高与舞台比例,再调走速和跳跃弧线;随后调攻击距离;最后才调镜头。镜头不能掩盖角色运动本身的问题。
|
||
|
||
**MOVE SYSTEM**
|
||
|
||
# 07 拳脚攻击与招式时间轴
|
||
|
||
## 7.1 普通攻击规格
|
||
|
||
每个普通技由 MoveData 描述,并由 MoveController 按 Tick 推进。MoveData 不仅记录起手/持续/收招,还包含位移、HitBox 轨迹、伤害、命中效果、取消窗口、资源变化和表现事件。
|
||
|
||
| **招式** | **定位** | **建议特征** |
|
||
|-----------------|---------------|--------------------------------------------------|
|
||
| **站轻拳 LP** | 近距离确认 | 4 Tick 起手;短收招;命中可连自身或取消必杀 |
|
||
| **站重拳 HP** | 高伤害 / 对空 | 8–10 Tick 起手;大 HitStop;可设置上半身对空判定 |
|
||
| **站轻脚 LK** | 中距离牵制 | 5 Tick 起手;较长脚部 HitBox;低伤害 |
|
||
| **站重脚 HK** | 远距离重击 | 10–12 Tick 起手;长收招;可造成击退或击倒 |
|
||
| **蹲轻脚 2LK** | 低段确认 | 低段;伤害低;命中后可接轻拳或必杀 |
|
||
| **跳重脚 j.HK** | 跳入攻击 | 空中可用;落地有硬直;根据落点决定正反向 |
|
||
|
||
## 7.2 招式阶段
|
||
|
||
| **阶段** | **逻辑** | **可发生事件** |
|
||
|--------------|--------------------------|------------------------------------------|
|
||
| **Startup** | 输入已接受,尚无攻击判定 | 前摇位移、无敌/装甲、取消来源检查 |
|
||
| **Active** | 一个或多个 HitBox 有效 | 命中、格挡、交易命中、多段间隔 |
|
||
| **Recovery** | HitBox 关闭,等待恢复 | 可被反击;部分招式开放命中取消 |
|
||
| **End** | 招式完成 | 返回 Idle / Air / Landing 或链入后续动作 |
|
||
|
||
## 7.3 取消规则
|
||
|
||
- Whiff Cancel:挥空时允许取消;MVP 默认关闭,避免无限安全试探。
|
||
|
||
- Hit Cancel:命中后允许普通技取消到指定必杀技。
|
||
|
||
- Block Cancel:被格挡时也可取消;通常比命中取消列表更严格。
|
||
|
||
- Chain Cancel:轻攻击可在命中后连到另一轻攻击或指定中攻击。
|
||
|
||
- Super Cancel:特定必杀技在命中/格挡时可取消为超必杀技。
|
||
|
||
- 取消只在 MoveData 的帧区间内有效,并且来源、目标、命中状态和资源条件全部满足。
|
||
|
||
## 7.4 连段与伤害缩放
|
||
|
||
| **规则** | **MVP 建议** |
|
||
|------------------|-----------------------------------------------------------|
|
||
| **连击成立** | 上一击造成的 HitStun 尚未结束,下一击在恢复前命中 |
|
||
| **伤害缩放** | 第 1 击 100%,第 2 击 90%,之后每击 −10%,最低 50% |
|
||
| **最低伤害** | 超必杀最后一击可设 20% 最低保障,避免长连段完全失去终结感 |
|
||
| **HitStun 衰减** | 连击达到 5 段后每段额外减少 1 Tick,避免无限连 |
|
||
| **重复招式限制** | 同一浮空连段中关键弹墙/浮空属性只触发一次 |
|
||
| **连击重置** | 受击者回到可行动状态、倒地结束或回合结算时重置 |
|
||
|
||
> **帧优势的基本检查**
|
||
>
|
||
> 命中优势 ≈ HitStun − 攻击者剩余收招;格挡优势 ≈ BlockStun − 剩余收招。MVP 不要求复杂数值,但每个招式都应能从帧表推导“命中后谁先动、格挡后是否可反击”。
|
||
|
||
**DEFENSE**
|
||
|
||
# 08 格挡、防御与受击规则
|
||
|
||
## 8.1 格挡意图
|
||
|
||
格挡不是一个可以随时强制进入的普通动作,而是角色在可防御状态下、检测到“远离对手”的方向输入后产生的 GuardIntent。HitResolver 在命中 Tick 使用该意图、姿态和攻击段位决定是否格挡成功。
|
||
|
||
| **攻击段位** | **站立格挡** | **蹲下格挡** | **空中格挡** |
|
||
|------------------------|--------------|--------------|--------------|
|
||
| **High 高段** | 可 | 不可 | MVP 不支持 |
|
||
| **Mid 中段** | 可 | 可 | MVP 不支持 |
|
||
| **Low 低段** | 不可 | 可 | MVP 不支持 |
|
||
| **Unblockable 不可防** | 不可 | 不可 | 不可 |
|
||
|
||
## 8.2 格挡成立条件
|
||
|
||
- 受击者当前状态允许格挡:Idle、Walk、Crouch 或可取消到格挡的恢复状态。
|
||
|
||
- 在命中 Tick 开始时存在有效 GuardIntent;方向按该 Tick 的 FacingSnapshot 解释。
|
||
|
||
- 攻击段位与受击者姿态匹配;不可防或投技类攻击直接绕过。
|
||
|
||
- 受击者未处于 GuardBreak、KO、不可防演出或明确禁止格挡的动作中。
|
||
|
||
- 命中来自身后时,MVP 仍按双方逻辑朝向判定;下一 Tick 才更新转身,避免同 Tick 双重解释。
|
||
|
||
## 8.3 格挡结果
|
||
|
||
| **项目** | **建议规则** |
|
||
|--------------|---------------------------------------------------------------------|
|
||
| **格挡硬直** | 由攻击 MoveData 给出;轻攻击 6–9 Tick,重攻击 12–18 Tick |
|
||
| **格挡推远** | 攻击者与防守者按比例分摊;角落时攻击者承担更多反作用位移 |
|
||
| **削血** | 普通技 0;必杀技 5%–15% 基础伤害;削血不能直接 KO(可配置) |
|
||
| **能量增长** | 攻击者命中格挡获得少量能量,防守者也获得更少能量 |
|
||
| **取消规则** | 攻击者可按 MoveData 在格挡后取消;防守者不可在 BlockStun 中普通行动 |
|
||
| **连续格挡** | BlockStun 期间若新攻击到达,重新计算段位并刷新硬直 |
|
||
|
||
## 8.4 受击类型
|
||
|
||
| **类型** | **用途** | **反应** |
|
||
|----------------|----------------------|----------------------------------|
|
||
| **LightHit** | 轻拳、轻脚 | 短 HitStop、轻微后仰、短硬直 |
|
||
| **HeavyHit** | 重拳、重脚、必杀 | 较长 HitStop、明显击退与受击动作 |
|
||
| **Launch** | 对空或浮空技 | 写入空中速度,进入 Launch 状态 |
|
||
| **Knockdown** | 扫腿、重击、超杀终结 | 落地后进入倒地与起身流程 |
|
||
| **Crumple** | 可选的重度受击 | 长站立硬直,可用于超杀前置 |
|
||
| **CounterHit** | 在对手攻击起手被命中 | 额外伤害或 HitStun,并显示提示 |
|
||
|
||
> **简化建议**
|
||
>
|
||
> MVP 先不做完美格挡、弹反、防御槽和受身。防御系统越复杂,越需要额外动画、UI、AI与平衡成本;先把高/中/低段与格挡硬直做正确。
|
||
|
||
**HIT DETECTION**
|
||
|
||
# 09 HitBox 与命中结算管线
|
||
|
||
## 9.1 判定体分类
|
||
|
||
| **判定体** | **归属** | **用途** | **实现建议** |
|
||
|------------------|----------------|--------------------------|--------------------------------------|
|
||
| **PushBox** | 角色 | 角色间实体推挤与角落挤压 | 固定矩形/胶囊;每 Tick 处理一次 |
|
||
| **HurtBox** | 角色骨骼或姿态 | 可被攻击命中的区域 | 头、躯干、腿等多个盒;随姿态轨迹变化 |
|
||
| **HitBox** | 招式或飞行道具 | 主动攻击判定 | 仅 Active 帧开启;携带 HitDefinition |
|
||
| **ProximityBox** | 可选 | 靠近时触发近身普通技 | 只用于选招,不直接造成命中 |
|
||
| **StageBox** | 场景 | 地面、边界与特殊区域 | 逻辑用简化体,视觉网格不参与战斗碰撞 |
|
||
|
||
## 9.2 判定轨迹
|
||
|
||
HitBox 与 HurtBox 不依赖运行时骨骼物理碰撞,而是由可编辑的 BoxTrack 描述。每个 Tick 根据招式帧或姿态帧读取局部位置、尺寸、旋转与标签,再转换到角色逻辑坐标。这样可以稳定调节判定,并在动画替换后保持规则可控。
|
||
|
||
- 优先使用矩形或胶囊;避免 MeshCollider 和复杂 Convex 碰撞。
|
||
|
||
- 每个 HitBox 携带 MoveInstanceId + HitGroupId,用于控制同一招式对同一目标的命中次数。
|
||
|
||
- 多段招式通过不同 HitGroup 或 RehitInterval 配置,不通过重复开关碰撞器猜测。
|
||
|
||
- 飞行道具使用独立 OwnerId、TeamId 与 ProjectileInstanceId,仍进入统一 HitResolver。
|
||
|
||
- 调试模式显示红色 HitBox、绿色 HurtBox、蓝色 PushBox,并标注 Tick 与招式 ID。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
S1["1. 收集同 Tick 的 HitBox × HurtBox 候选"] -->
|
||
S2["2. 过滤:阵营、自身、重复命中、无敌 / 装甲"] -->
|
||
S3["3. 判定格挡、高低段、交叉攻击与反击命中"] -->
|
||
S4["4. 处理同帧冲突:交易命中 / 显式优先级"] -->
|
||
S5["5. 计算伤害、连段缩放、削血与资源变化"] -->
|
||
S6["6. 写入 HitStop、HitStun / BlockStun、击退与浮空"] -->
|
||
S7["7. 派发视觉事件:特效、音效、震屏、慢镜头"] -->
|
||
S8["8. 记录 CombatLog 与回放输入,进入下一个 Tick"]
|
||
```
|
||
|
||
图 2 单个战斗 Tick 内的命中结算顺序
|
||
|
||
## 9.3 同帧冲突规则
|
||
|
||
| **场景** | **规则** |
|
||
|------------------------------|-----------------------------------------------------------------------|
|
||
| **双方普通攻击同 Tick 命中** | 默认交易命中:两边都应用结果;除非招式显式配置优先级或无敌 |
|
||
| **攻击命中飞行道具** | MVP 默认不相互抵消;后续可给飞行道具增加耐久与碰撞层 |
|
||
| **同一攻击命中多个 HurtBox** | 只生成一个 HitCandidate,使用命中点优先级最高的 HurtBox |
|
||
| **多段攻击同 Tick 重叠** | 按 HitGroupId 和 RehitInterval 去重;同目标每组最多结算一次 |
|
||
| **命中与 KO 同 Tick** | 先完成该 Tick 全部合法命中,再按结果进入 KO;表现上可选择超杀终结慢镜 |
|
||
| **格挡与被绕后同 Tick** | 按 Tick 开始时 FacingSnapshot 判断;下一 Tick 才转身 |
|
||
|
||
## 9.4 HitResult 数据
|
||
|
||
**统一命中结果对象**
|
||
|
||
```csharp
|
||
struct HitResult {
|
||
EntityId attacker;
|
||
EntityId defender;
|
||
MoveInstanceId moveInstance;
|
||
HitOutcome outcome; // Hit / Block / Armor / Invulnerable
|
||
int damage;
|
||
int chipDamage;
|
||
int hitStopAttacker;
|
||
int hitStopDefender;
|
||
int stunTicks;
|
||
Vec2 pushback;
|
||
Vec2 launchVelocity;
|
||
bool counterHit;
|
||
bool knockdown;
|
||
Vec2 contactPoint;
|
||
}
|
||
```
|
||
|
||
> **实现原则**
|
||
>
|
||
> 碰撞系统只回答“哪些判定体发生重叠”;HitResolver 才回答“这次重叠是否有效、是否格挡、造成多少伤害、进入什么状态”。不要把游戏规则写进 OnTriggerEnter。
|
||
|
||
**SPECIALS & SUPER**
|
||
|
||
# 10 必杀技、超必杀技与能量
|
||
|
||
## 10.1 必杀技组合建议
|
||
|
||
| **招式类型** | **战术作用** | **关键实现点** |
|
||
|--------------|----------------------------|---------------------------------------|
|
||
| **能量弹** | 远距离牵制、迫使跳跃或格挡 | 对象池、速度、寿命、命中组、场外回收 |
|
||
| **对空升击** | 惩罚跳跃、近身反击 | 起手无敌窗口、向上 HitBox、落地收招 |
|
||
| **突进踢** | 中距离接近、连段收尾 | 位移曲线、墙边推挤、命中/格挡不同收招 |
|
||
|
||
## 10.2 能量系统
|
||
|
||
| **事件** | **攻击者获得** | **防守者获得** |
|
||
|------------------|----------------|----------------|
|
||
| **普通技命中** | 2–5 | 1–3 |
|
||
| **普通技被格挡** | 1–3 | 1–2 |
|
||
| **必杀技命中** | 5–10 | 3–5 |
|
||
| **必杀技被格挡** | 3–6 | 2–4 |
|
||
| **受到重击** | — | 5–8 |
|
||
| **使用超必杀** | 消耗 100 | — |
|
||
|
||
*能量增长应全部来自 MoveData,不写死在攻击类型分支中。*
|
||
|
||
## 10.3 超必杀执行流程
|
||
|
||
> **1.** CommandRecognizer 检测到超必杀指令,并确认当前状态允许、能量为 100。
|
||
>
|
||
> **2.** 立即预占资源并创建 SuperMoveInstance,防止同 Tick 重复触发。
|
||
>
|
||
> **3.** 进入 8–15 Tick 的 SuperFreeze:对手、普通飞行道具与比赛计时暂停;施放者按配置推进或保持。
|
||
>
|
||
> **4.** 播放镜头拉近、角色闪光和蓄力音效;逻辑仍由 MoveTimeline 决定无敌与判定开启。
|
||
>
|
||
> **5.** 按多段 HitGroup 依次命中;每段有独立 HitStop、伤害与击退。
|
||
>
|
||
> **6.** 终结段应用 Knockdown 或特殊 KO 镜头;超杀结束后恢复正常镜头与 BattleTime。
|
||
|
||
| **规则项** | **建议** |
|
||
|--------------|-------------------------------------------------------|
|
||
| **超杀输入** | 236236 + 任意拳;总窗口 24 Tick,按键缓冲 5 Tick |
|
||
| **资源检查** | 必须在动作开始前满足;资源在 Enter 时扣除 |
|
||
| **起手无敌** | 示例 1–8 Tick;只作为招式数据,不由“超杀”类型自动赋予 |
|
||
| **画面冻结** | 逻辑冻结与表现冻结分离;UI、音效尾音可继续 |
|
||
| **连段缩放** | 遵循通用缩放,但终结段可有最低伤害保障 |
|
||
| **失败处理** | 资源不足时回退到普通拳;不可因指令部分匹配吞掉输入 |
|
||
|
||
> **原创性要求**
|
||
>
|
||
> 可以借鉴“飞行道具、对空、突进、超杀冻结”等类型设计,但角色造型、动作轮廓、招式名称、特效、音效、UI 与数值组合应原创,避免直接复刻现有作品。
|
||
|
||
**PRESENTATION**
|
||
|
||
# 11 动画、特效、音效与镜头
|
||
|
||
## 11.1 动画驱动策略
|
||
|
||
| **内容** | **权威来源** | **说明** |
|
||
|------------------|-----------------------------|--------------------------------|
|
||
| **当前动作与帧** | FighterState + MoveTimeline | 动画根据逻辑动作与 Tick 采样 |
|
||
| **HitBox 开关** | MoveData / HitboxTrack | 不依赖 Animation Event |
|
||
| **角色位移** | FighterMotor / MotionCurve | 普通战斗禁用自由 Root Motion |
|
||
| **受击与格挡** | HitResult | 结果确定后触发对应表现 |
|
||
| **音效与特效** | PresentationEvent | 允许丢帧补播,但不影响战斗结果 |
|
||
| **镜头** | CameraDirector | 消费角色位置与命中事件 |
|
||
|
||
## 11.2 动画状态建议
|
||
|
||
- 基础层:Idle、WalkF、WalkB、Crouch、Turn、JumpStart、JumpUp、Fall、Landing。
|
||
|
||
- 攻击层:每个普通技、必杀技与超必杀独立 Clip;按 MoveId 显式切换。
|
||
|
||
- 受击层:轻/重受击、上段/下段格挡、浮空、倒地、起身、KO。
|
||
|
||
- 面部或上半身叠加层仅用于非关键表现,不改变 HurtBox 和战斗姿态。
|
||
|
||
- 动画过渡时间应很短且可预测;攻击动作通常使用 0 或 1 Tick 的逻辑切换。
|
||
|
||
## 11.3 打击反馈事件包
|
||
|
||
| **反馈** | **轻击** | **重击 / 必杀** | **超必杀终结** |
|
||
|-------------|--------------|------------------------|--------------------------|
|
||
| **HitStop** | 4–6 Tick | 7–11 Tick | 10–16 Tick |
|
||
| **火花** | 小型、短寿命 | 较大、方向性强 | 多层特效 + 屏幕闪光 |
|
||
| **音效** | 清脆 | 低频冲击 + 武器/元素层 | 专属终结音与低频冲击 |
|
||
| **震屏** | 0–2 px | 3–7 px | 8–14 px;可在设置中减弱 |
|
||
| **镜头** | 通常不变 | 轻微推近或冲击抖动 | 拉近、冻结、跟随终结动作 |
|
||
| **飘字** | 可选 | Counter / Punish 提示 | Super / KO 强调 |
|
||
|
||
## 11.4 镜头规则
|
||
|
||
- 基础镜头朝向战斗平面,目标点为两角色中点;距离随角色间距变化。
|
||
|
||
- 确保两人屏幕边缘留有安全边距,且舞台边界不会暴露未制作区域。
|
||
|
||
- 跳跃时相机只跟随一定比例的 Y 高度,避免频繁上下晃动。
|
||
|
||
- HitStop 期间可添加短促 Impulse,但相机位置插值需使用 PresentationTime。
|
||
|
||
- 超杀镜头必须有超时回退;角色被 KO、演出被中断或对象销毁时强制恢复基础镜头。
|
||
|
||
> **无障碍与舒适度**
|
||
>
|
||
> 设置中提供“震屏强度、闪光强度、手柄震动、动态镜头”开关。关闭这些效果不应改变 HitStop、输入、判定和比赛结果。
|
||
|
||
**ARCHITECTURE**
|
||
|
||
# 12 技术架构与更新顺序
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph DATA["输入与数据"]
|
||
CD["Character / Move / Stage Data"]
|
||
IB["InputBuffer"] --> CR["CommandRecognizer"]
|
||
end
|
||
|
||
subgraph COMBAT["战斗域"]
|
||
BC["BattleClock<br/>固定 60 Tick"]
|
||
FC["FighterController<br/>StateMachine + Motor"]
|
||
MF["MatchFlow"]
|
||
MC["MoveController<br/>招式时间轴"]
|
||
CW["CollisionWorld<br/>Push / Hurt / Hit Box"]
|
||
HR["HitResolver<br/>统一命中结算"]
|
||
PS["ProjectileSystem"]
|
||
end
|
||
|
||
subgraph PRESENT["表现层"]
|
||
VA["VFX / Audio / 动画"]
|
||
CAM["CameraDirector"]
|
||
HUD["HUD / 菜单"]
|
||
end
|
||
|
||
CD --> FC
|
||
CD --> MC
|
||
CD --> PS
|
||
CR --> FC
|
||
BC --> FC
|
||
BC --> MF
|
||
FC --> MC
|
||
FC --> CW
|
||
MC --> CW
|
||
CW --> HR
|
||
HR --> FC
|
||
HR --> PS
|
||
PS --> CW
|
||
|
||
MF -.-> HUD
|
||
FC -.-> VA
|
||
FC -.-> CAM
|
||
FC -.-> HUD
|
||
HR -.-> VA
|
||
HR -.-> CAM
|
||
```
|
||
|
||
图 3 推荐的战斗域模块划分
|
||
|
||
## 12.1 核心模块
|
||
|
||
| **模块** | **职责** | **禁止事项** |
|
||
|-----------------------|------------------------------------------|--------------------------------|
|
||
| **BattleClock** | 固定 Tick、暂停、HitStop 域与帧步进 | 不读取玩家输入,不直接控制动画 |
|
||
| **InputService** | 设备采样、重绑定、写入 InputBuffer | 不决定招式,不改变角色状态 |
|
||
| **CommandRecognizer** | 匹配指令并生成动作请求 | 不扣资源,不直接播放动画 |
|
||
| **FighterController** | 聚合状态机、运动、生命、能量与动作实例 | 不直接搜索场景对象 |
|
||
| **MoveController** | 按 Tick 推进招式事件与取消窗口 | 不直接结算伤害 |
|
||
| **CollisionWorld** | 构建判定体、收集重叠候选 | 不处理格挡、伤害或 KO |
|
||
| **HitResolver** | 过滤、格挡、伤害、硬直、击退、资源与日志 | 不依赖特效对象是否存在 |
|
||
| **ProjectileSystem** | 生成、推进、回收飞行道具 | 不绕过 HitResolver |
|
||
| **MatchFlow** | 开场、计时、KO、回合与胜负 | 不持有角色招式细节 |
|
||
| **Presenter** | 动画、VFX、音效、镜头、HUD | 不反向决定战斗逻辑 |
|
||
|
||
## 12.2 每 Tick 更新顺序
|
||
|
||
> **1.** InputService 将设备状态汇总为 InputFrame,并写入每个玩家的 InputBuffer。
|
||
>
|
||
> **2.** BattleClock 判断全局暂停、超杀冻结与各实体 HitStop,确定本 Tick 谁可以推进。
|
||
>
|
||
> **3.** Fighter PreTick:识别指令、生成转移请求、处理已到期硬直。
|
||
>
|
||
> **4.** 状态机提交最高优先级转移;MoveController 推进当前招式帧并生成判定轨迹。
|
||
>
|
||
> **5.** FighterMotor 与 ProjectileSystem 计算位移;Stage/PushSolver 修正边界和角色重叠。
|
||
>
|
||
> **6.** CollisionWorld 重建本 Tick 的 Push/Hurt/Hit Box 并收集 HitCandidate。
|
||
>
|
||
> **7.** HitResolver 对全部候选排序和结算,写入生命、能量、硬直、击退与新状态请求。
|
||
>
|
||
> **8.** MatchFlow 检查 KO、时间结束与回合转换。
|
||
>
|
||
> **9.** Presenter 消费本 Tick 的只读快照与 PresentationEvent,更新动画、特效、音效、镜头和 HUD。
|
||
>
|
||
> **10.** CombatLog 记录输入摘要、状态摘要与命中结果,用于回放和问题复现。
|
||
|
||
**战斗主循环伪代码**
|
||
|
||
```csharp
|
||
void BattleTick() {
|
||
inputService.CaptureTickInputs();
|
||
battleClock.BeginTick();
|
||
foreach (var fighter in fighters) fighter.PreTick();
|
||
foreach (var fighter in fighters) fighter.CommitTransition();
|
||
foreach (var fighter in fighters) fighter.SimulateMoveAndMotor();
|
||
projectileSystem.Simulate();
|
||
collisionWorld.BuildSnapshot(fighters, projectiles);
|
||
hitResolver.Resolve(collisionWorld.CollectHitCandidates());
|
||
foreach (var fighter in fighters) fighter.PostTick();
|
||
matchFlow.EvaluateRound();
|
||
combatLog.RecordSnapshot();
|
||
presenter.PublishFrame();
|
||
}
|
||
```
|
||
|
||
## 12.3 事件分类
|
||
|
||
| **事件类型** | **是否可丢失** | **例子** |
|
||
|------------------------|-----------------|----------------------------------------|
|
||
| **Domain Command** | 不可 | 开始招式、扣能量、应用 HitResult |
|
||
| **Domain Event** | 不可 | FighterHit、RoundKO、ProjectileSpawned |
|
||
| **Presentation Event** | 可补播 / 可降级 | HitSpark、CameraShake、PlaySfx |
|
||
| **Telemetry Event** | 可批量 | 输入统计、帧耗时、招式使用率 |
|
||
|
||
**DATA**
|
||
|
||
# 13 数据配置与资源规范
|
||
|
||
## 13.1 CharacterData
|
||
|
||
| **字段组** | **示例字段** |
|
||
|--------------|----------------------------------------------------------|
|
||
| **身份** | CharacterId、显示名、阵营、默认皮肤 |
|
||
| **体型** | 身高、PushBox、站立/蹲姿 HurtBox 轨迹 |
|
||
| **移动** | 前走/后走速度、跳跃初速度、重力、落地硬直 |
|
||
| **资源** | 最大生命、最大能量、初始能量、受击能量倍率 |
|
||
| **动作映射** | Idle、Walk、Jump、Block、Hit、KO 与 MoveId 列表 |
|
||
| **表现** | AnimatorProfile、VFXProfile、AudioProfile、CameraProfile |
|
||
|
||
## 13.2 MoveData 核心字段
|
||
|
||
| **字段组** | **字段** | **说明** |
|
||
|------------|---------------------------------------|-------------------------------------------------------|
|
||
| **标识** | MoveId / DisplayName / Tags | 唯一 ID、编辑器名称与 Normal/Special/Super/Air 等标签 |
|
||
| **输入** | CommandId / Button / AllowedStates | 指令、攻击键、允许起招状态 |
|
||
| **时序** | Startup / ActiveSegments / Recovery | 全部使用整数 Tick |
|
||
| **命中** | Damage / HitLevel / HitStop / HitStun | 伤害、高低段、停顿与硬直 |
|
||
| **位移** | MotionCurve / Pushback / Launch | 攻击者位移、受击推远与浮空速度 |
|
||
| **判定** | HitboxTrack / HurtboxOverride | 逐 Tick 判定轨迹与姿态覆盖 |
|
||
| **防御** | BlockStun / Chip / GuardPush | 被格挡后的效果 |
|
||
| **资源** | MeterGain / MeterCost | 命中、格挡、挥空与使用成本 |
|
||
| **取消** | CancelWindows / CancelTargets | 时间区间、命中条件和目标标签 |
|
||
| **特殊** | Invuln / Armor / CounterHitBonus | 无敌、装甲、反击奖励 |
|
||
| **表现** | AnimationId / VFX / SFX / CameraCue | 只读消费的表现事件 |
|
||
|
||
**Unity 风格的数据对象示例**
|
||
|
||
```csharp
|
||
[CreateAssetMenu(menuName = "Fighting/Move Data")]
|
||
public sealed class MoveData : ScriptableObject {
|
||
public string moveId;
|
||
public MoveTag tags;
|
||
public CommandData command;
|
||
public int startupTicks;
|
||
public ActiveSegment[] activeSegments;
|
||
public int recoveryTicks;
|
||
public HitDefinition hit;
|
||
public HitboxTrack hitboxTrack;
|
||
public MotionTrack motionTrack;
|
||
public CancelWindow[] cancelWindows;
|
||
public InvulnerabilityWindow[] invulnerability;
|
||
public PresentationCue[] presentation;
|
||
}
|
||
```
|
||
|
||
## 13.3 资源目录建议
|
||
|
||
**建议的目录与归属**
|
||
|
||
```text
|
||
Assets/Game/
|
||
├── Battle/
|
||
│ ├── Core/ # Clock、状态机、命中、运动、回放
|
||
│ ├── Data/ # CharacterData、MoveData、StageData
|
||
│ ├── Editor/ # 帧表、判定轨迹与预览工具
|
||
│ └── Debug/ # Hitbox、输入、日志、帧步进
|
||
├── Characters/<CharacterId>/
|
||
│ ├── Animations/
|
||
│ ├── Moves/
|
||
│ ├── HitboxTracks/
|
||
│ ├── VFX/
|
||
│ ├── Audio/
|
||
│ └── Prefabs/
|
||
├── Stages/<StageId>/
|
||
├── UI/
|
||
└── Tests/
|
||
├── Unit/
|
||
├── Simulation/
|
||
└── PlayMode/
|
||
```
|
||
|
||
## 13.4 命名与版本
|
||
|
||
- 稳定 ID 使用小写蛇形:hero_01、st_lp、sp_projectile、su_finisher;显示名可本地化。
|
||
|
||
- 逻辑数据与表现资源分离:MoveData 不直接引用场景对象,只引用可加载资源 ID。
|
||
|
||
- 数据增加 schemaVersion;重大字段变更提供迁移脚本,而不是手工逐个修复。
|
||
|
||
- 所有平衡数值变更进入版本控制,并在提交说明中写明“旧值 → 新值 → 目的”。
|
||
|
||
- 角色 Prefab 只挂通用组件,不在 Prefab 上复制核心战斗脚本。
|
||
|
||
> **编辑器工具优先级**
|
||
>
|
||
> 最值得做的自定义工具是“招式时间轴 + HitBox/HurtBox 轨迹预览”。它应支持拖动 Tick、复制帧、镜像判定、显示动画参考姿态并即时运行单招测试。
|
||
|
||
**MATCH & UI**
|
||
|
||
# 14 UI、回合流程与设置
|
||
|
||
## 14.1 MatchFlow 状态
|
||
|
||
| **状态** | **持续 / 退出条件** | **允许内容** |
|
||
|-----------------|-------------------------|--------------------------------|
|
||
| **Loading** | 资源准备完成 | 不推进战斗 |
|
||
| **Intro** | 角色入场动画结束 | 镜头演出、不可操作 |
|
||
| **RoundReady** | “Round / Fight”演出结束 | 角色锁定、计时不动 |
|
||
| **Fighting** | KO 或时间归零 | 完整战斗逻辑 |
|
||
| **KOFreeze** | 短暂停顿结束 | 命中表现继续,禁止新输入 |
|
||
| **RoundResult** | 胜负演出完成 | 更新局数、播放胜利动作 |
|
||
| **MatchResult** | 玩家选择重开或退出 | 结果 UI |
|
||
| **Paused** | 关闭暂停 | BattleTime 停止,RealTime 继续 |
|
||
|
||
## 14.2 战斗 HUD
|
||
|
||
- 双方生命条:显示当前值、延迟损失值(白血)与 KO 状态。
|
||
|
||
- 双方能量条:0–100;满能量时有明确但不过度闪烁的提示。
|
||
|
||
- 回合标记:最多 2 个胜利点;当前回合和剩余时间居中。
|
||
|
||
- 连击与提示:Combo、Counter、Punish、Block;由 Domain Event 驱动。
|
||
|
||
- 训练/调试叠层:当前状态、MoveId、招式帧、帧优势、输入历史和判定框开关。
|
||
|
||
## 14.3 设置与可访问性
|
||
|
||
| **类别** | **设置项** |
|
||
|----------|---------------------------------------------------|
|
||
| **控制** | 键盘/手柄重绑定、摇杆死区、输入显示、简易指令开关 |
|
||
| **画面** | 分辨率、窗口模式、画质、动态模糊关闭、闪光强度 |
|
||
| **镜头** | 震屏强度、超杀镜头、镜头跟随强度 |
|
||
| **音频** | 总音量、音乐、音效、语音、手柄震动 |
|
||
| **游戏** | 回合数、时间、AI 难度、训练模式生命恢复 |
|
||
| **辅助** | 色盲友好 HUD、字幕、慢速训练、按键提示 |
|
||
|
||
> **UI 数据边界**
|
||
>
|
||
> HUD 只读取 BattleSnapshot,不直接持有 FighterController。这样暂停、回放、观战与未来联网时都可以复用同一套展示逻辑。
|
||
|
||
**AI & TRAINING**
|
||
|
||
# 15 AI 与训练木桩
|
||
|
||
## 15.1 MVP AI 结构
|
||
|
||
采用“感知 + 战术状态 + 效用评分”的轻量 AI。AI 不需要直接读取未来输入或命中结果;它只使用当前距离、双方状态、资源、角落位置和近期行为。决策间隔建议 4–8 Tick,并加入反应延迟。
|
||
|
||
| **战术状态** | **进入条件** | **候选行为** |
|
||
|--------------|-------------------------|--------------------------------------|
|
||
| **Neutral** | 双方可行动、距离中远 | 走位、能量弹、试探重脚、等待 |
|
||
| **Approach** | 距离过远或时间落后 | 前走、前跳、突进技 |
|
||
| **Pressure** | 对手在 BlockStun / 角落 | 轻攻击、延迟重击、必杀取消、后退诱骗 |
|
||
| **Defense** | 对手起攻或自身低血量 | 格挡、后退、对空、无敌技 |
|
||
| **Punish** | 检测到对手大收招 | 选择起手足够快且距离可达的招式 |
|
||
| **Combo** | 己方攻击命中确认 | 按预设连段脚本执行后续输入 |
|
||
|
||
## 15.2 难度差异
|
||
|
||
| **维度** | **简单** | **普通** | **困难** |
|
||
|--------------|----------------|------------------|------------------------|
|
||
| **反应延迟** | 18–24 Tick | 10–16 Tick | 6–10 Tick |
|
||
| **指令失误** | 较高 | 中等 | 低 |
|
||
| **格挡倾向** | 只格挡明显攻击 | 按距离与动作判断 | 能识别常见高低段 |
|
||
| **连段长度** | 1–2 击 | 3–4 击 | 4–6 击并使用资源 |
|
||
| **反制知识** | 无 | 有限对空/惩罚 | 基于帧差和距离选择惩罚 |
|
||
| **随机性** | 高 | 中 | 低但仍保留风格权重 |
|
||
|
||
## 15.3 训练木桩
|
||
|
||
- 站立、蹲下、跳跃、第一击后格挡、随机格挡。
|
||
|
||
- 受击后恢复生命、能量固定、位置重置。
|
||
|
||
- 录制 5–10 秒输入并循环播放,用于测试防守与惩罚。
|
||
|
||
- 显示连击伤害、起始伤害、缩放、帧优势和可行动 Tick。
|
||
|
||
- 一键重置到舞台中央或角落。
|
||
|
||
> **禁止“读心”**
|
||
>
|
||
> 困难 AI 可以更快、更准,但不应读取玩家尚未生效的输入,也不应在 0 Tick 内完美反应。可接受的优势来自更短反应延迟、更好的距离判断与更完整的连段脚本。
|
||
|
||
**PERFORMANCE & FUTURE**
|
||
|
||
# 16 性能、回放与联机预留
|
||
|
||
## 16.1 性能预算
|
||
|
||
| **项目** | **目标** |
|
||
|----------------|----------------------------------------------------------|
|
||
| **战斗 Tick** | 平均 \< 1.5 ms,99 分位 \< 3 ms(双角色 + 常规飞行道具) |
|
||
| **碰撞判定体** | 每角色 HurtBox 4–8 个;单招 HitBox 1–4 个 |
|
||
| **运行时分配** | 战斗关键路径 0 B / Tick;列表和事件缓冲预分配 |
|
||
| **飞行道具** | 常规同时存在 ≤ 16;使用对象池 |
|
||
| **VFX / 飘字** | 对象池 + 最大并发;超限时降级而非阻塞 |
|
||
| **动画** | 避免每 Tick 字符串查找;缓存哈希与状态 ID |
|
||
|
||
## 16.2 回放
|
||
|
||
首版回放只需保存初始随机种子、角色/场景数据版本与每 Tick 的 InputFrame。回放时重新运行战斗逻辑,并周期性记录状态哈希。若哈希不一致,立即输出首个分歧 Tick、角色状态、位置、生命与当前招式。
|
||
|
||
- 回放文件不保存动画、特效或音频状态。
|
||
|
||
- 每 60 Tick 记录一次轻量状态哈希,用于自动检测非确定性。
|
||
|
||
- 版本不兼容时明确拒绝播放,不尝试静默修复。
|
||
|
||
- Bug 报告可自动附带最近 10 秒输入与 CombatLog。
|
||
|
||
## 16.3 回滚联机预留
|
||
|
||
MVP 不实现联网,但核心域应避免阻断未来回滚:战斗逻辑固定 Tick、输入驱动、状态可序列化、表现层可重建。真正接入网络时,需进一步处理浮点确定性、快照大小、回滚重演性能与输入延迟。
|
||
|
||
| **现在就做** | **以后再做** |
|
||
|---------------------------------------|------------------------------|
|
||
| 固定 Tick、输入帧、战斗快照、状态哈希 | 网络传输、预测输入、回滚窗口 |
|
||
| 战斗域不依赖场景查找与动画事件 | 跨平台确定性与浮点策略 |
|
||
| 表现事件带唯一 ID,允许回滚撤销/去重 | 观战、断线重连、匹配与反作弊 |
|
||
| 对象池和可重建飞行道具 | 网络带宽压缩与同步协议 |
|
||
|
||
> **现实边界**
|
||
>
|
||
> 不要为了“以后可能联网”过早引入复杂框架。只要保持固定 Tick、输入驱动、数据可序列化和表现解耦,单机原型就已经保留了最有价值的联机基础。
|
||
|
||
**DEBUGGING**
|
||
|
||
# 17 调试工具与可观测性
|
||
|
||
## 17.1 必做工具
|
||
|
||
| **工具** | **功能** | **验收标准** |
|
||
|-------------------|--------------------------------------|--------------------------------|
|
||
| **帧步进** | 暂停后每次推进 1 Tick / 10 Tick | 状态、动画采样和判定体同步推进 |
|
||
| **输入历史** | 显示最近 30–60 Tick 的方向和按键 | 标出已消费输入与指令匹配区间 |
|
||
| **判定框显示** | Hit/Hurt/Push Box 颜色区分 | 镜像、缩放和移动后仍准确 |
|
||
| **招式面板** | MoveId、当前帧、阶段、取消窗口 | 能看到有效 HitBox 与无敌窗口 |
|
||
| **战斗日志** | 命中候选、过滤原因、HitResult | 可按角色、招式与 Tick 筛选 |
|
||
| **状态快照** | 位置、速度、状态、生命、能量、Facing | 一键复制为文本用于 Bug 单 |
|
||
| **输入录制/回放** | 录制并重复执行短序列 | 多次播放结果哈希一致 |
|
||
|
||
## 17.2 CombatLog 示例
|
||
|
||
**命中日志应能回答“为什么发生这个结果”**
|
||
|
||
```text
|
||
T=1842 P1 move=st_hp frame=8 phase=Active
|
||
candidate: hitbox=body_0 target=P2 hurtbox=torso
|
||
guardIntent=true stance=Standing hitLevel=Mid => BLOCK
|
||
result: blockStun=14 hitStop=8 guardPush=(0.42,0)
|
||
meter: P1 +4, P2 +2
|
||
transition: P2 -> BlockStun(14), P1 stays st_hp frame=8
|
||
```
|
||
|
||
## 17.3 自动监控断言
|
||
|
||
- 角色生命、能量与状态枚举始终在合法范围。
|
||
|
||
- 同一 Fighter 同 Tick 只能提交一个最终状态转移。
|
||
|
||
- MoveController 帧不得超出总帧数;已结束招式必须释放 MoveInstance。
|
||
|
||
- 同一 HitGroup 不得在禁止重击间隔内重复命中同一目标。
|
||
|
||
- KO 后不得接受玩家输入或生成新的攻击 HitBox。
|
||
|
||
- 角色逻辑位置不得离开舞台边界,Z 逻辑坐标必须为 0。
|
||
|
||
- 回放状态哈希不一致时自动中止并导出差异。
|
||
|
||
> **调试不是“开发者模式装饰”**
|
||
>
|
||
> 格斗游戏的大多数问题都发生在特定 Tick 和特定状态组合。没有输入历史、帧步进和判定框,团队会把时间花在猜测而不是定位。
|
||
|
||
**DELIVERY PLAN**
|
||
|
||
# 18 开发里程碑与任务拆分
|
||
|
||
以下计划以 1 名程序 + 1 名通才美术/动画的原型团队为参考。若是个人开发,可按同一顺序推进,但不要并行制作大量内容。每个阶段必须通过验收门再进入下一阶段。
|
||
|
||
| **阶段** | **主要交付** | **验收门** |
|
||
|-------------------|-------------------------------------------------|--------------------------------------------------|
|
||
| **M0 工程骨架** | BattleClock、输入帧、基础数据、空场景、调试面板 | 帧步进与输入历史可用;固定 Tick 不受渲染帧率影响 |
|
||
| **M1 运动原型** | 双角色生成、行走、转身、跳跃、PushBox、镜头 | 无穿透、无越界;30/60/120 FPS 手感一致 |
|
||
| **M2 命中闭环** | 普通技、Hit/Hurt Box、HitStop、受击、格挡、KO | 镜像角色能完成一局;结果可由 CombatLog 解释 |
|
||
| **M3 招式系统** | 指令识别、取消、飞行道具、对空、突进、超杀 | 录制输入可稳定触发;资源和多段命中正确 |
|
||
| **M4 比赛产品化** | HUD、回合流程、暂停、设置、本地双人、训练木桩 | 从启动到重开无阻断;关键设置可保存 |
|
||
| **M5 AI 与打磨** | AI、VFX/SFX、镜头、两角色内容、性能优化 | 完整 Demo 可连续游玩 30 分钟无卡死或明显漏判 |
|
||
| **M6 发布准备** | 测试回归、手柄覆盖、打包、日志与崩溃信息 | 验收清单全绿;已知问题有明确说明 |
|
||
|
||
## 18.1 工作量粗估
|
||
|
||
| **模块** | **人日范围** | **备注** |
|
||
|--------------------------|--------------|-----------------------------------------------------|
|
||
| **战斗核心与调试** | 8–12 | 输入、时钟、状态机、运动、判定、命中与工具 |
|
||
| **普通技 / 必杀 / 超杀** | 5–8 | 不含高质量动画制作 |
|
||
| **比赛流程与 UI** | 3–5 | 基础 HUD、设置、回合与暂停 |
|
||
| **AI 与训练模式** | 3–5 | 简单效用 AI + 训练木桩 |
|
||
| **表现整合** | 5–8 | 动画接入、特效、音效、镜头与反馈 |
|
||
| **测试与优化** | 4–7 | 自动测试、性能、手柄、打包与回归 |
|
||
| **合计** | 28–45 | 占位素材的功能型 Demo;个人开发按技能和素材情况浮动 |
|
||
|
||
## 18.2 推荐任务拆分
|
||
|
||
- 每个功能任务都包含:数据、运行时、调试显示、测试场景与验收用例。
|
||
|
||
- 角色动作与判定由同一 MoveId 串联,避免动画名、招式名和代码枚举不一致。
|
||
|
||
- 每新增一个招式,必须同时提交帧表、HitboxTrack、命中/格挡结果和训练模式验证步骤。
|
||
|
||
- 每次调整核心结算顺序,都运行固定回放集并比较状态哈希。
|
||
|
||
- 表现任务在战斗事件稳定后接入,不直接修改战斗核心以“配合动画”。
|
||
|
||
> **第一可玩顺序**
|
||
>
|
||
> Idle → Walk → Jump → 一个普通技 → HitBox/HurtBox → HitStop/HitStun → Block → KO。完成这条链路前,不做超杀镜头、AI 或复杂 UI。
|
||
|
||
**QA**
|
||
|
||
# 19 测试方案与验收标准
|
||
|
||
## 19.1 自动测试层级
|
||
|
||
| **层级** | **覆盖内容** | **示例** |
|
||
|-------------------|-----------------|-----------------------------------------------|
|
||
| **Unit** | 纯算法与数据 | 指令匹配、伤害缩放、格挡段位、优先级排序 |
|
||
| **Simulation** | 无渲染战斗 Tick | 固定输入运行 600 Tick,检查状态哈希与最终生命 |
|
||
| **PlayMode** | 场景与组件集成 | 跳跃接地、舞台边界、飞行道具回收、HUD 更新 |
|
||
| **Golden Replay** | 回归回放集 | 10–30 条已知战斗录像在每次构建中重放 |
|
||
| **Manual** | 手感与设备 | 键盘/多种手柄、帧率、震屏、视觉可读性 |
|
||
|
||
## 19.2 核心验收用例
|
||
|
||
| **ID** | **场景** | **通过标准** |
|
||
|------------|-------------------------------|------------------------------------------|
|
||
| **MOV-01** | 前后行走并互相推挤 | 不穿透、不抖动、不越界;角落分摊正确 |
|
||
| **MOV-02** | 30/60/120 FPS 下连续跳跃 | 起跳高度、滞空 Tick 与落点一致 |
|
||
| **INP-01** | 快速输入 236+P | 在宽容窗口内稳定触发,超窗不触发 |
|
||
| **INP-02** | 236236+P 且能量不足 | 不吞键;按优先级回退到合法动作 |
|
||
| **ATK-01** | 轻拳命中站立对手 | 伤害、HitStop、HitStun、推远与特效一致 |
|
||
| **BLK-01** | 站防高/中/低段 | 高/中成功,低段失败并进入受击 |
|
||
| **BLK-02** | 蹲防高/中/低段 | 中/低成功,高段失败并进入受击 |
|
||
| **HIT-01** | 双方同 Tick 普通攻击 | 按交易规则双方受击,日志顺序稳定 |
|
||
| **HIT-02** | 多 HurtBox 与一个 HitBox 重叠 | 只结算一次,命中点选择一致 |
|
||
| **SP-01** | 飞行道具命中/格挡/出界 | 三种路径均正确回收且无重复命中 |
|
||
| **SP-02** | 对空技无敌窗口 | 窗口内忽略指定攻击,窗口外正常受击 |
|
||
| **SU-01** | 满能量超杀 | 只扣一次资源;冻结、镜头、多段与终结正确 |
|
||
| **KO-01** | 同 Tick 生命归零与多段后续 | 只结算合法段;进入 KO 后无新攻击 |
|
||
| **REP-01** | 同输入回放 20 次 | 最终状态与中间哈希完全一致 |
|
||
|
||
## 19.3 功能完成定义(Definition of Done)
|
||
|
||
- 设计数据已填写且通过合法性校验,没有魔法数字散落在运行时代码。
|
||
|
||
- 功能可在 Debug HUD 中观察关键状态与 Tick。
|
||
|
||
- 至少有 1 个自动测试或固定回放覆盖主要逻辑。
|
||
|
||
- 键盘与至少一种手柄可用,重绑定后仍正常。
|
||
|
||
- 30/60/120 FPS 下结果一致;暂停、慢动作与 HitStop 不影响输入匹配。
|
||
|
||
- 不存在已知的状态卡死、重复命中、越界、资源重复扣除或 KO 后继续行动。
|
||
|
||
- 表现层缺失时战斗逻辑仍可完整运行;表现对象销毁不会破坏比赛。
|
||
|
||
> **发布门槛**
|
||
>
|
||
> 完整对战连续运行 30 分钟,无崩溃、无永久卡死、无明显输入丢失;核心回放集全部通过;关键路径战斗 Tick 在目标机器上满足性能预算。
|
||
|
||
**RISKS & APPENDIX**
|
||
|
||
# 20 风险、原创边界与附录
|
||
|
||
## 20.1 主要风险与缓解
|
||
|
||
| **风险** | **表现** | **缓解措施** |
|
||
|------------------|------------------------------------------|------------------------------------------|
|
||
| **动画驱动逻辑** | 判定漏发、过渡不同步、改动画导致规则变化 | 逻辑帧表权威;动画只采样与展示 |
|
||
| **范围持续膨胀** | 投技、防反、联网、角色内容同时开工 | 严格按 M0–M6 验收门推进 |
|
||
| **输入手感差** | 指令过严或误触发,玩家无法稳定出招 | 输入录制、匹配日志、可配置宽容窗口 |
|
||
| **判定难调** | 动画好看但判定不稳定或不可读 | 独立 HitboxTrack 编辑器与帧步进 |
|
||
| **碰撞不确定** | 动态刚体、回调顺序导致同帧结果变化 | 运动学控制 + 收集后统一结算 |
|
||
| **表现反向侵入** | 镜头/特效脚本改生命或状态 | Domain / Presentation 事件边界与代码审查 |
|
||
| **内容制作成本** | 每个招式需要动作、判定、特效、音效 | 先做少量高辨识度招式,复用事件模板 |
|
||
| **知识产权风险** | 造型、动作、招式名和 UI 过度相似 | 建立原创设定与视觉语言;保留素材来源记录 |
|
||
|
||
## 20.2 原创边界检查
|
||
|
||
- 不要直接使用现有格斗游戏的角色姓名、服装轮廓、招式名称、语音、UI、标志或特效图样。
|
||
|
||
- 通用机制如走、跳、格挡、飞行道具、对空、能量槽和超杀冻结可以采用,但表达方式应原创。
|
||
|
||
- 动作捕捉、音效、字体、模型与特效包需确认商业许可范围,并保存许可证与购买凭证。
|
||
|
||
- 宣传文案使用“2.5D 对战格斗”描述,不以他人商标作为产品名称或核心卖点。
|
||
|
||
## 附录 A:首个灰盒角色帧表示例
|
||
|
||
| **招式** | **输入** | **起/持/收** | **伤害** | **硬直 H/B** | **用途** |
|
||
|--------------|----------|------------------|----------|--------------|----------------------------|
|
||
| **站轻拳** | LP | 4 / 2 / 8 | 40 | 10 / 7 | 近身确认;命中可取消必杀 |
|
||
| **站重拳** | HP | 9 / 3 / 18 | 90 | 16 / 12 | 重击;部分帧可对空 |
|
||
| **站轻脚** | LK | 5 / 3 / 10 | 45 | 11 / 8 | 中距离试探 |
|
||
| **站重脚** | HK | 11 / 3 / 22 | 105 | 18 / 14 | 长距离;反击风险高 |
|
||
| **蹲轻脚** | 2+LK | 5 / 2 / 9 | 35 | 9 / 7 | 低段;可链轻拳 |
|
||
| **跳重脚** | 空中 HK | 7 / 5 / 着地6 | 80 | 14 / 11 | 跳入攻击 |
|
||
| **能量弹** | 236+P | 12 / 投射物 / 22 | 80 | 15 / 12 | 远程牵制;削血 8 |
|
||
| **对空升击** | 623+P | 5 / 6 / 28 | 110 | 击倒 / 15 | 1–6 Tick 上半身无敌 |
|
||
| **突进踢** | 214+K | 10 / 5 / 20 | 100 | 17 / 13 | 接近与连段收尾 |
|
||
| **超必杀** | 236236+P | 7 / 多段 / 35 | 300 | 击倒 / 20 | 消耗 100;起手冻结 10 Tick |
|
||
|
||
*H/B = HitStun / BlockStun。所有数值仅为原型起点,不代表最终平衡。*
|
||
|
||
## 附录 B:首轮实现清单
|
||
|
||
| **完成** | **任务** | **完成** | **任务** |
|
||
|----------|----------------------------------------|----------|----------------------------------------------|
|
||
| □ | BattleClock 与 60 Tick 主循环 | □ | InputBuffer 与方向相对化 |
|
||
| □ | CommandRecognizer 与输入日志 | □ | FighterStateMachine 与转移优先级 |
|
||
| □ | FighterMotor、跳跃、舞台边界与 PushBox | □ | MoveData、MoveTimeline 与取消窗口 |
|
||
| □ | HitBox/HurtBox 轨迹与调试显示 | □ | HitResolver、格挡、伤害、HitStop、硬直与击退 |
|
||
| □ | 飞行道具、对空技、突进技与超必杀 | □ | MatchFlow、HUD、KO、暂停与重开 |
|
||
| □ | 训练木桩、AI、输入回放与状态哈希 | □ | 动画、VFX、SFX、镜头与可访问性设置 |
|
||
|
||
## 附录 C:项目启动时的 10 个决定
|
||
|
||
> **1.** 确认战斗是严格 2D 平面,还是允许 Z 轴闪避;本方案默认严格 2D。
|
||
>
|
||
> **2.** 确认普通技数量与按钮数;本方案默认 4 攻击键。
|
||
>
|
||
> **3.** 确认格挡采用背向方向,是否提供独立 Guard 辅助键。
|
||
>
|
||
> **4.** 确认是否支持蹲姿与高低段;本方案建议首版支持。
|
||
>
|
||
> **5.** 确认每角色必杀技与超杀数量;本方案为 3 + 1。
|
||
>
|
||
> **6.** 确认是否有动态刚体需求;战斗角色默认不使用动态刚体。
|
||
>
|
||
> **7.** 确认首版仅单机/本地对战,不在 MVP 中实现联网。
|
||
>
|
||
> **8.** 确认动画与模型来源、许可和可用动作数量。
|
||
>
|
||
> **9.** 确认调试工具必须随核心功能同步交付。
|
||
>
|
||
> **10.** 确认第一可玩验收后再投入完整美术与角色内容。
|
||
|
||
> **最终建议**
|
||
>
|
||
> 先做一个角色镜像对战,完整打通“一次输入 → 一个动作 → 一个判定 → 一次命中/格挡 → 一次状态恢复 → 一次 KO”。这条链路稳定后,新增角色与招式才会变成可控的内容生产,而不是继续堆技术债。
|