GAS 网络模型(Gameplay Ability System)
GAS 是 UE 做技能/属性/状态的标准框架,也是网络同步的重灾区——ASC 复制模式选错带宽翻倍、预测键用错技能表现割裂、Meta Attribute 复制了就漏伤害数值。本篇只讲 GAS 的网络侧:三种复制模式、预测键机制、属性复制的执行端、Cue 的双路径。
一句话结论
ASC 三模式按「GE 复制给谁」权衡带宽,预测键让客户端先演服务器后确认,Meta Attribute 只在服务器消化不复制。
场景问题
打个比方:GAS 像医院的病历系统。
GameplayEffect是一条条医嘱(中毒 30 秒、攻击力 +10);AttributeSet是化验单上的数值(血量、蓝量);GameplayTag是病历首页的状态标签(眩晕中、燃烧中,还带层数);GameplayCue是病房里看得见的表现(打点滴的动作、屏幕变红)。三种复制模式就是「病历给谁看」:
Full是把完整病历发给所有人;Mixed是完整病历只给本人,别人只看到你打着点滴(玩家角色最常用);Minimal是谁都不发病历,只让人看到打点滴的动作(海量小兵)。选错的后果很直接:一堆小兵的完整医嘱群发全场,带宽当场爆。
FPredictionKey是预约单号:你说「我要放技能」,本地先按预期演起来(动画、扣蓝),同时把单号报给服务器;服务器权威执行后按这个单号回话——认了就无缝转正,不认就按单号把刚才那些临时改动全撤回。Meta Attribute(如
Damage)像医生手里的计算草稿纸:算「这次该扣多少血」的中间量,算完就擦掉。病人只需要看化验单上的血量(Health),草稿纸没必要也不该发出去——复制它既浪费带宽又白送信息。
「技能怎么做到客户端点了立刻有反馈、又不被作弊?」——GAS 的答案是一套预测(prediction)机制:客户端用 FPredictionKey 标记「我预测放了这个技能」,本地立刻演,服务器权威执行后确认或否决,否决就回滚。加上属性(血/蓝)复制、GameplayEffect(GE)复制、GameplayCue(特效)同步,构成 GAS 的网络全貌。面试常问「ASC 三种复制模式区别」和「Meta Attribute 为什么不复制」。
实现方案
1. ASC 三种复制模式
AbilitySystemComponent 的 ReplicationMode 决定 GameplayEffect(GE)复制给谁——这是 GAS 带宽的最大开关:
| 模式 | GE 复制给谁 | GameplayTag/Cue | 适用对象 |
|---|---|---|---|
| Full | 所有客户端都收到完整 GE | 全复制 | 单人游戏,或少量关键 Actor |
| Mixed | GE 只复制给 owner,其他人只收 Tag/Cue(Multicast) | Tag 全复制、Cue 广播 | 玩家角色(最常用) |
| Minimal | GE 不复制给任何人,只走 Tag/Cue | Tag/Cue 复制 | AI/小兵等大量非玩家单位 |
选错的后果:一个 100 人 MOBA,如果小兵 ASC 用 Full,每个小兵的每条 GE(每个 buff/debuff)复制给所有人——带宽爆炸。小兵应该用 Minimal(玩家不需要知道小兵的完整 GE 明细,只要看到特效);玩家自己用 Mixed(自己需要完整 GE 做 UI,别人只看表现)。
2. 预测模型:FPredictionKey
客户端 服务器
│ 按技能 → 生成 FPredictionKey │
│ 本地立即执行(预测):播动画/扣蓝 │
│── 激活技能RPC(带PredictionKey)──▶│ 权威执行
│ │ 确认/否决该 PredictionKey
│◀──── 复制结果 + Key 确认 ────────│
│ 确认→本地预测生效(无缝) │
│ 否决→回滚撤销预测的改动 │
FPredictionKey:客户端生成的预测标识,绑定这次预测里所有的临时改动。服务器确认后,客户端的预测「转正」;否决则回滚。FScopedPredictionWindow:在服务器 RPC 处理内开一个作用域,让这段时间内应用的 GE 关联到客户端的 PredictionKey,实现「服务器执行结果对齐客户端预测」。- 可预测 vs 不可预测:能安全本地先演的(播动画、暂扣蓝、加临时 Tag)可预测;有随机性/依赖服务器独有数据/不可逆的(掉落、真正的伤害结算)不预测,等服务器。
- 预测失败回滚:否决时撤销预测期间的属性变化、Tag、Cue。GameplayCue 有
WhileActive(持续态,回滚要 Remove)和OnRemove/Removed(结束时触发)路径,预测失败要正确收尾避免特效残留。
3. AttributeSet 复制与执行端
属性(血、蓝、攻击力)放在 AttributeSet 里,用 FGameplayAttributeData 类型并声明复制:
FGameplayAttributeData:属性的存储类型,BaseValue(基础值)+CurrentValue(当前值,被 buff 修改后)。复制的是它,配 RepNotify 触发GAMEPLAYATTRIBUTE_REPNOTIFY。PreAttributeChange:属性将变时的钳制钩子(如血量 clamp 到 [0, MaxHealth]),两端都会调(表现层钳制)。PostGameplayEffectExecute:GE 执行后的钩子,只在服务器(权威)跑,用于「消化」Meta Attribute、触发死亡等权威逻辑。- Meta Attribute(如
Damage):一种只在服务器用的中转属性,不复制。GE 把伤害写进DamageMeta Attribute,PostGameplayEffectExecute里服务器读取它、从Health里扣、然后清零。它是「本次要施加多少伤害」的临时载体,客户端不需要也不该看到——复制它反而泄露且无意义。
高频坑:Meta Attribute 不能复制
Damage/Healing 这类 Meta Attribute 设成复制是常见错误。它们只是服务器计算伤害的中间变量,客户端拿到没用(客户端看的是 Health 的变化)。复制它浪费带宽还可能被逆向读取。
4. GameplayTag 与 GameplayCue
- GameplayTag 计数复制:ASC 上的 Tag 是带计数的(同一 Tag 可叠加多层),计数通过复制同步。客户端据此判断状态(眩晕中、燃烧中)。
- GameplayCue 双路径:Cue 是「表现层」(特效、音效),有两条触发路径——
- Multicast 路径:服务器通过 ASC 广播 Cue 给所有相关客户端(可靠或不可靠)。
- 本地预测路径:客户端在预测技能时本地立即触发 Cue(不等服务器),预测失败再回滚。
- 两路径要协调避免重复播放:预测本地已播的,收到服务器 Multicast 时要能识别不重复。
- Lyra 参照:Epic 的 Lyra 示例工程是 GAS 网络配置的实战参考——玩家 ASC 用 Mixed、大量用 GameplayCue Notify、属性用标准 AttributeSet 模式。研究 Lyra 比读文档更能理解实际配置。
5. 一句话记住这几组容易混的概念
| 一组 | 差别一句话 | 类比 |
|---|---|---|
| GE vs Attribute vs Tag vs Cue | GE 是「医嘱」,Attribute 是「化验数值」,Tag 是「状态标签」,Cue 是「看得见的表现」 | 病历四件套 |
| Mixed vs Minimal | Mixed 完整病历给本人、别人只看表现;Minimal 谁都不给病历,只留表现 | 玩家 vs 小兵 |
PreAttributeChange vs PostGameplayEffectExecute | 前者是「值将变时钳制」,两端都跑;后者是「GE 执行后的权威结算」,只在服务器 | 护士照上限拦一手 vs 医生签字确认 |
| 普通 Attribute vs Meta Attribute | 普通的要复制、客户端要看(Health);Meta 的只在服务器中转、绝不复制(Damage) | 化验单 vs 草稿纸 |
| GAS 预测 vs CMC 预测 | 同一哲学「先演后裁」,但 GAS 靠 FPredictionKey 撤销改动,CMC 靠 SavedMove 队列重放输入 | 撤回一批临时记账 vs 从某一步重走一遍路 |
一条主线串起来:按下技能→生成预约单号→本地先演(可预测的部分)→上报服务器权威执行→按单号确认或撤回→最终结果靠 Attribute 复制 + Tag/Cue 让所有人看到。判断某件事能不能预测,就问一句:错了撤得回来吗?动画、临时扣蓝撤得回;掉落、真实伤害结算撤不回,那就别预测。
为什么这么做
三模式分层复制:GE 是 GAS 里数据量最大的东西(每个 buff/debuff/加成一条)。玩家自己需要完整 GE 做 UI(Mixed 给 owner),别人只需看表现(Tag/Cue);海量 AI 连完整 GE 都不必给任何客户端(Minimal)。按「谁真的需要这份数据」分层,是 GAS 省带宽的核心。
预测键机制:技能要即时反馈(点了就演)又要服务器权威(防作弊)。PredictionKey 让客户端先演、服务器后裁、错了回滚——和 CMC 移动预测同一哲学,见 移动预测与回滚。
Meta Attribute 不复制:伤害计算是服务器权威的瞬时过程,中间量客户端既用不上又不该见。只复制最终的 Health,让客户端通过血量变化感知结果。
为什么别的选择不行
- 所有 ASC 都用 Full:海量 AI 的 GE 全量复制给所有人,带宽数量级爆炸。
- 复制 Meta Attribute:泄露服务器计算中间量、浪费带宽,客户端拿到也没用。
- 技能完全不预测(等服务器):点技能到反馈有一个 RTT 延迟,操作感差。
- 技能完全客户端权威(不确认):作弊者随意放技能、改伤害,见 反作弊。
- Cue 只走 Multicast 不做本地预测:owner 放技能也要等服务器广播才有特效,反馈延迟。
沉淀结论
GAS 网络:ASC 三模式 Full(全复制 GE)/Mixed(GE 只给 owner,别人收 Tag/Cue,玩家常用)/Minimal(GE 不复制,AI 用)。预测靠 FPredictionKey + FScopedPredictionWindow,客户端先演服务器确认/否决回滚。属性用 FGameplayAttributeData,PostGameplayEffectExecute 只在服务器消化 Meta Attribute(不复制)。Tag 计数复制、Cue 走 Multicast + 本地预测双路径。参照 Lyra。
记忆口诀
三模式:Full 全复制GE(单人) / Mixed GE只给owner别人收Tag+Cue(玩家) / Minimal GE不复制(AI)
预测:FPredictionKey 标记 / ScopedPredictionWindow 对齐 / 客户端先演 / 服务器确认或否决回滚
属性:FGameplayAttributeData / PreAttributeChange 两端钳制 / PostGameplayEffectExecute 仅服务器
Meta Attribute:Damage 只在服务器消化 / 不复制 / 客户端看 Health 变化
Cue:Multicast 路径 + 本地预测路径 / 协调防重复播
内容来源
综合整理。主要参考:Epic 官方文档 Gameplay Ability System、GAS 官方文档中的网络章节、Lyra 示例工程、社区经典 tranek《GAS Documentation》(GitHub)。
相关专题:预测回滚的同源思路见 移动预测与回滚;属性复制底层(RepNotify/COND_)见 属性复制;技能激活的 Server RPC 校验见 RPC 与 服务器权威与反作弊。
自测:合上资料能说清楚吗?
ASC 三种复制模式怎么选?
参考答案
按「GameplayEffect 复制给谁」权衡带宽:Full(GE 复制给所有客户端,用于单人或少量关键 Actor);Mixed(GE 只复制给 owner,其他人只收 Tag/Cue,玩家角色最常用——自己需要完整 GE 做 UI,别人只看表现);Minimal(GE 不复制给任何人,只走 Tag/Cue,海量 AI/小兵用)。选错如小兵用 Full 会带宽爆炸。
FPredictionKey 解决什么?流程是什么?
参考答案
解决技能既要即时反馈又要服务器权威。客户端按技能时生成 FPredictionKey,本地立即预测执行(播动画、暂扣蓝),激活 RPC 带上 key 发服务器;服务器权威执行并确认或否决该 key;确认则客户端预测转正无缝衔接,否决则回滚撤销预测期间的属性/Tag/Cue 改动。FScopedPredictionWindow 让服务器执行的 GE 对齐到客户端 key。与 CMC 移动预测同哲学。
为什么 Meta Attribute(如 Damage)不复制?
参考答案
Meta Attribute 是服务器计算伤害的中间中转量:GE 把伤害写进 Damage,PostGameplayEffectExecute(只在服务器跑)读取它从 Health 扣血再清零。客户端看的是 Health 的变化,不需要也不该看到 Damage。复制它浪费带宽、可能被逆向读取、且客户端拿到无意义。