在 Unity 开发动作游戏时,真正耗费时间的往往不是角色移动,而是整套战斗系统的搭建。从技能系统、Buff 系统、属性系统,到受击反馈、武器系统、动画事件、AI,再到各种编辑器工具,这些模块彼此关联,稍有设计不合理,后期维护成本就会迅速增加。
Combat System Framework就是一款面向动作游戏开发的完整战斗框架,它最大的特点并不是提供了多少技能,而是采用了一套数据驱动(Data-Driven)+ Gameplay Tag + ScriptableObject的架构,将整个战斗系统模块化、解耦,并配套了一套完整的动画编辑工具,大幅降低动作游戏开发的复杂度。
本文将从整体架构出发,分析它的核心实现原理,以及这些设计为什么值得借鉴。
一、整体架构
Combat System Framework 可以看成由六大系统组成:
Gameplay Tag │ ┌──────────────┼──────────────┐ │ │ │ Ability System Buff System Attribute System │ │ │ └──────────────┼──────────────┘ │ Damage System │ ┌──────────────┴──────────────┐ │ │ Animation Notify Weapon System │ │ └──────────────┬──────────────┘ │ Character Controller可以看到,Gameplay Tag 是整个框架的核心。
所有系统几乎都围绕 Tag 工作,而不是直接依赖对象引用。
这种设计思想其实和 Unreal Engine 的 Gameplay Ability System(GAS)十分相似。
二、Gameplay Tag——整个框架的核心
传统 Unity 项目中,经常会看到这样的代码:
if(state==PlayerState.Attack)或者
if(animator.GetBool("Attack"))随着项目越来越大,这种方式会产生大量字符串和枚举。
Combat System Framework 使用的是Gameplay Tag。
例如:
Ability.Combat.Attack Ability.Combat.HeavyAttack State.Invincible State.Dead Weapon.Sword Buff.Poison这些 Tag 形成了一棵树。
例如:
Ability ├── Combat │ ├── Attack │ ├── HeavyAttack │ └── Dash └── Magic这样做最大的优势就是支持层级匹配。
例如:
Ability.Combat.Attack属于
Ability.Combat也属于
Ability因此可以快速判断:
角色是否正在施放 Combat 技能?而不需要列举几十个技能。
FNV-1a Hash 提高匹配效率
Tag 本质还是字符串。
如果每一帧都:
Ability.Combat.Attack进行字符串比较,效率并不高。
因此框架使用:
FNV-1a 64bit Hash
把字符串提前转换成:
uint64例如:
Ability.Combat.Attack ↓ 0xAE1930F23C...运行时比较:
ulong == ulong速度远高于字符串比较。
这是很多大型游戏都会采用的方法。
三、Ability System——技能系统
整个技能系统完全基于 ScriptableObject。
例如:
Light Attack.asset Heavy Attack.asset Dash.asset Jump.asset每个 Asset 描述:
- 技能名称
- 冷却时间
- 消耗
- 动画
- Tag
- 是否可实例化
- 技能逻辑
角色真正运行时:
Player ↓ Ability Component ↓ Ability Asset ↓ Execute()这样最大的好处就是:
技能配置与代码完全分离。
策划只需要修改 Asset。
程序无需修改代码。
Instancing Policy
技能支持不同实例策略。
例如:
单实例
Dash始终只有一个实例。
每次创建
FireBall每释放一次都会创建新的对象。
每角色实例
例如:
Charge Attack每个角色拥有独立状态。
这种设计可以避免大量状态共享问题。
四、Attribute System——属性系统
框架中的属性系统同样采用 Tag 管理。
例如:
Attribute.Health Attribute.Mana Attribute.Stamina每个 Attribute 包含:
Current Max Regen 事件当属性变化时:
Health -= 20系统自动广播:
OnHealthChanged OnHealthEmpty OnHealthRecoveredUI、AI、Buff 都可以监听这些事件。
无需互相引用。
自动恢复
例如:
Mana ↓ 每秒 +5或者
Stamina ↓ 停止攻击后恢复这些都属于 Attribute 自身逻辑。
五、Buff System——Buff 系统
Buff 同样采用 ScriptableObject。
例如:
Poison.asset Heal.asset Barrier.asset每个 Buff 可以配置:
持续时间 是否叠加 最大层数 Tick 时间例如:
Poison 每秒掉血 持续10秒系统实际上维护:
Timer ↓ Tick ↓ Apply Effect这种设计非常适合:
DOT
HOT
持续减速
持续回血
等效果。
六、Damage System——伤害系统
框架没有直接依赖具体角色。
而是定义:
IDamager IDamageable任何对象只要实现:
TakeDamage()即可参与战斗。
例如:
玩家 怪物 木箱 炸药桶全部统一处理。
这样实现了非常好的解耦。
Hit Reaction
受到攻击后:
系统根据:
攻击优先级 ↓ 受击动作自动选择:
轻击 击退 击飞 倒地这也是动作游戏中非常重要的一环。
七、Weapon System
框架支持:
近战
远程
投射物
AOE 技能。
例如:
Sword ↓ 近战碰撞Bow ↓ Projectile投射物支持:
- 贝塞尔曲线
- 螺旋轨迹
- 环形生成
- 波浪生成
因此不仅适用于动作游戏。
也可以制作:
弹幕游戏
ARPG
MOBA
等。
八、Animation Notify——动画驱动战斗
Combat System Framework 最大亮点之一,就是把动画作为战斗流程的驱动中心。
传统 Unity 中,大多数开发者都会使用 Animation Event 来控制攻击判定、播放音效或生成特效。但 Animation Event 存在几个明显问题:
- 事件只能逐个添加,编辑效率低;
- 无法批量复制、移动;
- 对复杂技能时间轴支持较差;
- 缺少可视化管理。
因此该框架开发了一套完整的Notify Timeline。
开发者可以像视频编辑软件一样:
- 拖拽 Notify
- 框选多个事件
- Copy / Paste
- 删除
- Undo
- 时间轴缩放
整个动画事件变成可视化编辑。
Notify 的实现原理
所有 Notify 都继承统一基类:
publicabstractclassNotify{publicabstractvoidExecute();}例如:
Spawn Effect Play Audio Camera Shake Launch Projectile Equip Weapon Trigger Ability全部只是不同 Notify。
时间轴播放到对应时间:
Timeline ↓ Notify ↓ Execute()因此扩展新的事件几乎不用修改编辑器代码。
只需要:
继承 Notify ↓ 重写 Execute()即可自动注册。
这种插件化设计非常优雅。
九、Root Motion 工具
很多动作游戏都会遇到:
动画位移和角色移动不同步。
框架提供:
Root Motion 提取工具。
可以:
动画 ↓ 提取轨迹 ↓ 显示运动路径开发者可以提前观察:
角色这一招到底移动多少距离。
非常适合:
冲刺
突进
翻滚
跳跃攻击。
十、编辑器工具链
Combat System Framework 不仅仅是一套运行时框架,还内置了大量编辑器扩展,包括:
- Animation Clip 编辑器
- Gameplay Tag ID Generator
- Notify Timeline 编辑器
- Root Motion 可视化
- 自定义 Property Drawer
- Tag Filter
- Preview Window
尤其是实时预览窗口(Preview Window),开发者无需进入 Play Mode,就可以:
- 播放动画;
- 拖动时间轴定位关键帧;
- 实时预览粒子特效;
- 检查武器挂点;
- 验证攻击时机。
这种所见即所得的工作流,能够明显提升动画调试效率,减少频繁运行游戏进行验证的时间成本。
十一、为什么这种架构更容易扩展?
Combat System Framework 的设计遵循了几个现代游戏框架的重要原则:
第一,数据驱动。技能、Buff、属性等内容全部由 ScriptableObject 配置,新增内容通常不需要修改核心代码,策划和程序可以并行工作。
第二,模块解耦。Gameplay Tag、接口(IDamageable、IDamager)和事件机制,使各个系统之间保持低耦合,减少直接引用带来的维护成本。
第三,开放扩展。无论是 Ability、Notify 还是 Buff,都采用基类 + 继承的方式进行扩展,新功能可以作为插件式模块接入,而无需修改已有逻辑。
第四,编辑器驱动开发。大量工作从运行时转移到编辑器完成,提升了开发效率,也降低了调试成本。
总结
Combat System Framework 并不是一个简单的角色控制器,而是一套完整的动作游戏战斗开发框架。它借鉴了现代 AAA 游戏常见的架构思想,以 Gameplay Tag 为核心,结合 ScriptableObject 数据驱动设计,将技能、属性、Buff、伤害、武器、动画通知等系统有机整合在一起。同时,配套的可视化动画时间轴、Root Motion 工具和实时预览窗口,大幅优化了动作开发流程。
当然,这套框架也有一定的学习门槛。开发者需要理解 Unity 的动画系统、Animation Event、Animation Curve、ScriptableObject 等基础知识,才能真正发挥它的优势。对于希望快速搭建ARPG、类魂(Soulslike)、动作冒险、Hack-and-Slash等项目的中高级 Unity 开发者来说,它不仅可以作为生产级战斗系统直接使用,更是一套值得深入研究和借鉴的战斗框架架构范例。
关于这个资源的更多信息,可以私信我,或者关注下方公众号进行学习交流