主题
技能系统API与属性对照
定位差异速览
| 维度 | 官方(res/lua/se_pub) | 作者版(地图侧 LuaSource) |
|---|---|---|
| 单元类型 | Ability / AbilityManager 为 SDK 注册的 Unit 类型 | 自定义预设类型(ability / ability_manager / ability_anchor),运行时 UnitType = Script |
| 数据声明 | meta JSON(meta/data/ability.json、meta/unit/ability_type.lua) | @type 注解 → Attributes KV(GetAttribute) |
| 对外入口 | 全局 Packages.ability_system.*(沙盒白名单包) | 地图内 require("server.packages.ability_system.api");编辑器侧为 ECA 积木面 eca.lua |
| 实例 API | ability:Method() 实例方法 | (unit, slotIndex) 闭包 handler 方法(经 AbilityRegistry 取 handler) |
| 事件机制 | ability:ConnectEvent/FireEvent(惰性 Signal)+ 命名 RemoteEvent | 挂在该实例下的 BindableEvent 事件单位(FindFirstChild(name):Connect)+ 单通道 RemoteEvent(action 路由) |
| 时间轴/锚点 | 原生:顶层 AnchorInfo/TimelineInfo,常驻 Anchor 对象自连 OnCastStart、Task:Delay 点火 | 复用官方编辑链路 + 镜像到声明字段 AnchorInfos/TimelineInfos;锚点执行由 16 个锚点类型脚本承担 |
| 锚点动作 | 作者在锚点 config 回调字段(Start/Break/End/Complete)里写逻辑 | 内置 16 个锚点类型(anchor_scripts/*.lua 壳 + anchors/*.lua 逻辑),属性以 ABILITY_ANOSTATE_* 等前缀暴露 |
| 跨端通信 | 每个 action 命名一个 RemoteEvent | 单 RemoteEvent "AbilitySystem" + {action, args} 载荷 |
预设类型对照
| 作者版预设 | 注解 | @title | 根/子 | template_id | 官方对应 |
|---|---|---|---|---|---|
ability | ---@export_prefab_type ability | 技能 | root Script,children {LocalScript},extends Script | map://preset/u3fd5003ad72406da4f50a9600730285 | Ability Unit 类型 |
ability_manager | ---@export_prefab_type ability_manager | 技能背包 | 同上 | map://preset/u014968df4aa4427aebac4388ed79bf7 | AbilityManager Unit 类型 |
ability_anchor | ---@export_prefab_type ability_anchor | 锚点 | root Script | map://preset/uccfb9dbe3f4428bb972096ba01f1f25 | 官方无对应预设类型(锚点是 AnchorInfo 数据节点,非独立预设) |
来源:作者版
common/packages/ability_system/editor.lua;官方为 SDK 内建类型。
结构体对照
| 作者版 | 定义 | 官方对应 |
|---|---|---|
ability_system.AbilityInfo | { AssetId: String(style:AssetResource, unit_types:["ability"]), Index: Int }(common/.../data.lua) | AbilityInfo:{ AbilityAsset: String(style:AssetResource, unit_types:Ability), Index: Int }(meta/data/ability_info.json) |
差异:字段名
AssetId↔AbilityAsset。
包级 API 对照
官方包 API
服务端(server/ability_system.lua 返回表,Packages.ability_system.*):
| 函数 | 参数 |
|---|---|
AddAbility | (unit, abilityId, abilityIndex) |
GetAbility | (unit, abilityIndex) |
GetAbilities | (unit) |
GetAbilityByPrefab | (unit, prefabKey) |
RemoveAbility | (unit, abilityIndex) |
ReplaceAbility | (unit, slotIndex, newPrefabKey) |
CastAbility | (unit, abilityIndex, releasePoint, releaseDirection, releaseTarget) |
StopAbility | (unit, abilityIndex) |
AccumulateAbility | (unit, abilityIndex) |
StopAccumulateAbility | (unit, abilityIndex) |
BreakAccumulateAbility | (unit, abilityIndex) |
SetAbilityToSlot | (unit, ability, slotIndex) |
RemoveAbilityByKey | (unit, abilityKey) |
ForbidSkillSlot | (unit, slotIndex, grayout) |
ActiveSkillSlot | (unit, slotIndex) |
ForbidAbility | (markAbility, unit, targetAbility, duration, showGreyOut, recoverOnCastEnd) |
GetAbilitiesFromIndexRange | (unit, startIndex, endIndex) |
客户端(client/ability_system.lua 返回表):
| 函数 | 参数 |
|---|---|
AddAbility | (unit, abilityData, abilityIndex) → FireServer |
CastAbility | (unit, abilityIndex, releasePoint, releaseDirection, releaseTarget) → FireServer |
StopAbility | (unit, abilityIndex) → FireServer |
GetAbility | (unit, abilityIndex) → 本地 AbilityManager 查询 |
AccumulateAbility | (unit, abilityIndex, ...) → FireServer |
StopAccumulateAbility | (unit, abilityIndex) → FireServer |
GetUIManager | () |
Register | (domain, key, value)(= Registry.Register) |
辅助:
AbilityUtils.GetAbilityManager(unit)(common/utils.lua)、Registry.Register/Get/GetAll(common/registry.lua)。 ECA 声明(api.lua,仅声明)另含AddAbilityTest(player, ability_id)/CastAbilityTest(player, ability_index)。
作者版 API 三层
(a) 服务端包 API(server/packages/ability_system/api.lua,AbilityServerAPI):
| 函数 | 参数 |
|---|---|
AddAbility | (unit, abilityKey, slotIndex) |
GetAbility | (unit, abilityIndex) |
GetAbilityByScript | (abilityScript) |
CastAbility | (unit, abilityIndex, releasePoint, releaseDir, releaseTarget) |
StopAbility | (unit, abilityIndex) |
AccumulateAbility | (unit, abilityIndex) |
SwitchNextAbility | (unit, parentSlotIndex) |
SetAbilityToSlot | (unit, ability, slotIndex) |
RemoveAbilityByKey | (unit, abilityKey) |
RemoveAbility | (unit, slotIndex) |
GetAbilities | (unit) |
GetAbilitiesFromIndexRange | (unit, startIndex, endIndex) |
RegisterEvents | () |
(b) 客户端包 API(client/packages/ability_system/api.lua,AbilityClientAPI):
| 函数 | 参数 |
|---|---|
GetManagerForUnit | (unit) |
GetAbility | (unit, abilityIndex) |
RequestCast | (manager, abilityIndex, releasePoint, releaseDir, releaseTarget) |
RequestStop | (manager, abilityIndex) |
RequestSwitchNext | (manager, parentSlotIndex) |
RequestAccumulate | (manager, abilityIndex) |
GetUIManager | () |
Register | (domain, key, value) |
StartClientLifecycle | () |
(c) ECA 蛋码面(server/packages/ability_system/eca.lua):65 个 ---@export_eca_func(含 31 个 ---@value_only 查询积木)+ 1 个 ---@export_eca_prefab_event(eca.CastStart)。命名约定 *XxxAtSlot(对槽位操作)/*XxxToSlot(放入槽位)/*XxxByPrefab(按预设筛选)。
完整积木清单:
- 动作类(32):
AddAbilityToSlot、CastAbilityAtSlot、StopAbilityAtSlot、RemoveAbilityAtSlot、RemoveAbilityByPrefab、MoveAbilityToSlot、UpgradeAbilityAtSlot、DowngradeAbilityAtSlot、IncreaseAbilityLevelAtSlot、InterruptCastAtSlot、InterruptAccumulateAtSlot、ModifyChargeCountAtSlot、EnterCDAtSlot、SetCurrentCDAtSlot、RemoveAbilitySelfAtSlot、SetLimitationAtSlot、SetDisableOnRollingAtSlot、SetCanUseOnUncontrolAtSlot、SetCanUseWhenFreezedAtSlot、SetAbilityLevelAtSlot、SetAbilityMaxLevelAtSlot、SetChargeCountAtSlot、SetMaxChargeCountAtSlot、SetChargeConfigAtSlot、SetReleaseDistanceAtSlot、SetReleaseRadiusAtSlot、ChangeReleaseDistanceAtSlot、ChangeReleaseRadiusAtSlot、SetAffectWidthAtSlot、ChangeAffectWidthAtSlot、ForbidSkillSlot、ActiveSkillSlot、SwitchAbilityOnceAtSlot、SwitchAbilityToSlotAtSlot - 查询类(30):
GetAbilityAtSlot、GetAbilities、GetAbilitiesFromIndexRange、GetAbilityCDAtSlot、GetAbilityCdTimeAtSlot、GetAbilityLevelAtSlot、GetAbilityMaxLevelAtSlot、GetChargeCountAtSlot、GetMaxChargeCountAtSlot、GetChargeIntervalAtSlot、GetChargeLeftTimeAtSlot、IsInChargeAtSlot、CanUseAbilityAtSlot、CanUpgradeAbilityAtSlot、GetAccumulateRatioAtSlot、GetLimitationAtSlot、IsInCDAtSlot、IsPointerTypeAtSlot、GetPrefabKeyAtSlot、GetOwnerAtSlot、GetAbilityNameAtSlot、GetReleaseDistanceAtSlot、GetReleaseRadiusAtSlot、GetAffectWidthAtSlot、GetReleasePointAtSlot、GetReleaseDirectionAtSlot、GetReleaseTargetAtSlot、IsValidTargetAtSlot、GetValidTargetsInRangeAtSlot、(动作中的SetChargeLeftTimeAtSlot)
包级 API 逐项映射
| 官方 API | 作者版等价 | 状态 |
|---|---|---|
AddAbility(unit, id, index) | AbilityServerAPI.AddAbility(unit, key, slot) / eca AddAbilityToSlot | ✅(无「同槽同预设复用」差异:作者版同 key 复用现有实例) |
GetAbility | AbilityServerAPI.GetAbility / eca GetAbilityAtSlot | ✅ |
GetAbilities | AbilityServerAPI.GetAbilities / eca GetAbilities | ✅ |
GetAbilitiesFromIndexRange | AbilityServerAPI.GetAbilitiesFromIndexRange | ✅ |
GetAbilityByPrefab | —(作者版仅有 GetAbilityByScript) | ❌ 缺(架构 §9.3 已登记) |
RemoveAbility | AbilityServerAPI.RemoveAbility / eca RemoveAbilityAtSlot | ✅ |
RemoveAbilityByKey | AbilityServerAPI.RemoveAbilityByKey / eca RemoveAbilityByPrefab | ✅ |
ReplaceAbility | — | ❌ 缺 |
CastAbility | AbilityServerAPI.CastAbility / eca CastAbilityAtSlot | ✅ |
StopAbility | AbilityServerAPI.StopAbility / eca StopAbilityAtSlot | ✅ |
AccumulateAbility | AbilityServerAPI.AccumulateAbility | ✅ |
StopAccumulateAbility | —(作者版 endAccumulate(false) 只经 handler;无独立包 API) | ⚠️ 部分(ECA 无对应积木) |
BreakAccumulateAbility | eca InterruptAccumulateAtSlot(内部 endAccumulate(true)) | ✅(语义等价,未走独立 API) |
SetAbilityToSlot | AbilityServerAPI.SetAbilityToSlot / eca MoveAbilityToSlot | ✅ |
ForbidSkillSlot / ActiveSkillSlot | eca ForbidSkillSlot / ActiveSkillSlot(handler.forbidSlot) | ✅(仅 ECA 面,无包 API) |
ForbidAbility | — | ❌ 缺 |
| — | AbilityServerAPI.GetAbilityByScript | ➕ 作者版额外 |
| — | AbilityServerAPI.SwitchNextAbility(子技能切换) | ➕ 作者版额外(官方经 ability:SwitchAbilityOnce) |
| — | AbilityClientAPI.RequestCast/RequestStop/RequestSwitchNext/RequestAccumulate | ➕ 作者版拆分为「请求」函数(官方客户端直接 CastAbility 即 FireServer) |
| — | AbilityClientAPI.StartClientLifecycle | ➕ 作者版额外(客户端生命周期自举) |
Register / GetUIManager | 同名(作者版 client api) | ✅ |
技能实例 API 对照(方法级)
官方是 ability:方法();作者版是 handler 闭包方法(AbilityRegistry.getAbilityHandler(script) 取得),并由 eca.lua 包装为槽位积木。下表「作者版」列给出 handler 方法(handler.*)与 ECA 积木。
基础 / 事件
| 官方实例方法 | 作者版 handler / ECA | 状态 |
|---|---|---|
GetOwner() | script.Parent.Parent(被 eca.GetOwnerAtSlot 暴露) | ✅ |
SetAbilityOwner(ownerId) | 由 manager 写 OwnerId 属性(无同名 API) | ⚠️ 内部 |
IsValidTarget(target) | TargetFilter.isValidTarget / eca IsValidTargetAtSlot | ✅ |
GetEvent(eventName) / ConnectEvent / FireEvent | handler.ConnectEvent(eventName, func);事件用 BindableEvent 单位(FindFirstChild(name):Connect) | ⚠️ 机制不同 |
GetName() | script.Name(eca GetAbilityNameAtSlot) | ✅ |
GetDescription() | — | ❌ 缺 |
GetIcon() | —(Icon 属性存在,但无 ECA/查询接口) | ❌ 缺 |
GetPrefabKey() | 属性 AbilityPresetKey(eca GetPrefabKeyAtSlot) | ✅ |
RemoveSelf() | handler.removeSelf() / eca RemoveAbilitySelfAtSlot | ✅ |
施法 / 蓄力
| 官方实例方法 | 作者版 handler / ECA | 状态 |
|---|---|---|
CanUse() | handler.canUse() / eca CanUseAbilityAtSlot | ✅ |
StartCast(rp, dir, target) | handler.startCast(rp, dir, target) / eca CastAbilityAtSlot | ✅ |
BreakCast() | handler.breakCast() / eca InterruptCastAtSlot | ✅ |
EndCast(is_break) | handler.endCast(broken)(无 ECA 积木,属内部) | ⚠️ 内部 |
StartAccumulate() | handler.startAccumulate() | ✅ |
EndAccumulate() | handler.endAccumulate(broken) | ✅ |
BreakAccumulate() | handler.endAccumulate(true) / eca InterruptAccumulateAtSlot | ✅ |
GetAccumulateRatio() | handler.getAccumulateRatio() / eca GetAccumulateRatioAtSlot | ✅ |
GetReleaseDirection() / GetReleasePoint() / GetReleaseTarget() | 同名 handler / eca GetReleaseDirectionAtSlot 等 | ✅ |
GetReleasePointList() / GetReleaseDirectionList() | — | ❌ 缺(作者版无多指示器) |
GetReleaseDistance/Radius/AffectWidth | 同名 handler / eca Get*AtSlot | ✅ |
SetReleaseDistance/Radius/AffectWidth | 同名 handler / eca Set*AtSlot | ✅ |
ChangeReleaseDistance/Radius/AffectWidth | 同名 handler(仅 Set/Change 三部由 eca 暴露;ECA 有 Change*AtSlot) | ✅ |
GetValidTargetsInRange(height) | TargetFilter.getValidTargetsInRange / eca GetValidTargetsInRangeAtSlot | ✅ |
IsPointerType(type) | eca IsPointerTypeAtSlot(读 PointerType 属性) | ✅ |
IsTargetType(type) | — | ❌ 缺 |
CD / 充能 / 升级 / 限制 / 子技能
| 官方实例方法 | 作者版 handler / ECA | 状态 |
|---|---|---|
EnterCD(cdTime) | handler.enterCD(cdTime) / eca EnterCDAtSlot | ✅ |
SetCurrentCD(cdTime) | handler.setCurrentCD(cdTime) / eca SetCurrentCDAtSlot | ✅ |
GetLeftCD() | handler.getLeftCD() / eca GetAbilityCDAtSlot | ✅ |
GetCdTime() | handler.getCdTime() / eca GetAbilityCdTimeAtSlot | ✅ |
IsInCD() | 读 InCD 属性 / eca IsInCDAtSlot | ✅ |
GetChargeCount/MaxChargeCount/Interval/LeftTime/IsInCharge | 同名 handler / eca Get*AtSlot | ✅ |
SetChargeCount/MaxChargeCount/LeftTime/ChangeChargeCount | 同名 handler / eca Set*AtSlot、ModifyChargeCountAtSlot | ✅ |
SetChargeConfig(enable, maxCount, chargeType, interval, amount) | handler.setChargeConfig(...) / eca SetChargeConfigAtSlot | ✅ |
Upgrade() / CanUpgrade() | handler.upgrade(delta) / handler.canUpgrade() / eca UpgradeAbilityAtSlot、CanUpgradeAbilityAtSlot | ✅(作者版 upgrade 带 delta) |
SetLevel/SetMaxLevel/IncreaseLevel/DecreaseLevel | 同名 handler / eca SetAbilityLevelAtSlot、SetAbilityMaxLevelAtSlot、IncreaseAbilityLevelAtSlot、DowngradeAbilityAtSlot | ✅ |
AddUseCondition(key, func) / RemoveUseCondition(key) | 同名 handler(无 ECA 积木) | ⚠️ 仅 Lua |
GetLimitation(type) | handler.getLimitation(type) / eca GetLimitationAtSlot | ✅ |
SetLimitation(type, enable) | handler.setLimitation(type, enable) / eca SetLimitationAtSlot | ✅ |
SetDisableOnRolling(enable) | setLimitation(Roll) / eca SetDisableOnRollingAtSlot | ✅ |
SetCanUseOnUncontrol(enable) | setLimitation(UnControllable) / eca SetCanUseOnUncontrolAtSlot | ✅ |
SetCanUseWhenFreezed(enable) | setLimitation(Freezed) / eca SetCanUseWhenFreezedAtSlot | ✅(作者版补了 Freezed=8 位,官方枚举无) |
SetParentAbilitySlot() / SetChildAbilitySlot(childIndex) / SwitchAbilityOnce() | group.switchTo/activateNext / eca SwitchAbilityOnceAtSlot、SwitchAbilityToSlotAtSlot | ✅(实现机制不同) |
PickTargetInReleaseRange(releasePoint)(客户端) | — | ❌ 缺 |
作者版 handler 额外方法(官方无同名)
getId、getSignals、getScript、getManager、_getRawAttribute、isAccumulating、onChargeTick、_stopCharge、_tryStartCharge、canPick。
属性(字段)对照
官方属性来源:
meta/data/ability.json(编辑面板 schema)+meta/unit/ability_type.lua(运行时类型注册,含运行时字段)。 作者版属性来源:server/packages/ability_system/ability_script.lua的@type注解(编辑即入 Attributes KV)。
技能配置属性
| 官方属性 | 官方类型/默认 | 作者版属性 | 作者版类型/默认 | 状态 |
|---|---|---|---|---|
Name | String / "技能预设" | —(用脚本 Name + AbilityPresetKey) | — | ⚠️ 缺字段 |
Desc | String / "描述1" | — | — | ❌ 缺 |
Description | String / "技能预设的描述" | — | — | ❌ 缺 |
Icon | String / "official://image/14103"(style IconResource) | Icon | String / ""(style IconResourceV2) | ✅(默认/风格不同) |
CdTime | Float / 1.0 | CdTime | number / 3.0 | ✅(默认不同) |
CastTime | Float / 1.0 | CastTime | number / 0.5 | ✅(默认不同) |
EnableAccumulate | Bool / false | EnableAccumulate | boolean / false | ✅ |
MaxAccumulateTime | Float / 1.0 | MaxAccumulateTime | number / 1.0 | ✅ |
AccumulateFinishTime | Float / 1.0 | — | — | ❌ 缺 |
Upgradable | Bool / false | Upgradable | boolean / false | ✅ |
MaxLevel | Int / 1 | MaxLevel | integer / 5 | ✅(默认不同) |
LevelRequirements | Array<Int> / [] | LevelRequirements | Int[] / {} | ✅ |
IsChargeConsuming | Bool / false | IsChargeConsuming | boolean / false | ✅ |
ChargeType | Int enum / 0 | ChargeType | Int enum / 0 | ✅ |
MaxChargeCount | Int / 1 | MaxChargeCount | integer / 5 | ✅(默认不同) |
ChargeInterval | Float / 1.0 | ChargeInterval | number / 1.0 | ✅ |
ChargeAmount | Int / 1 | ChargeAmount | integer / 1 | ✅ |
UseLimitation | Int 位掩码 / 1 | UseLimitation | Int enum / 0(多 Freezed=8) | ✅(枚举多一位,默认不同) |
ReleaseType | Int enum / 0 | ReleaseType | Int enum / 0 | ✅ |
ReleaseDistance | Float / 10.0 | ReleaseDistance | number / 10.0 | ✅ |
ReleaseRadius | Float / 3.0 | ReleaseRadius | number / 3.0 | ✅ |
AffectWidth | Float / 1.0 | AffectWidth | number / 1.0 | ✅ |
TargetType | Int enum / 1 | TargetType | Int enum / 1 | ✅ |
TargetFilterType | Array<String> / [] | TargetFilterType | String[] / {} | ✅(作者版为自由字符串数组,无枚举约束) |
TargetFilterCamp | Int enum / 1(CampRelationType) | TargetFilterCamp | Int enum / 0 | ✅(默认不同) |
TargetRequiredTags | Array<String> / [] | TargetRequiredTags | String[] / {} | ✅ |
TargetIgnoredTags | Array<String> / [] | TargetIgnoredTags | String[] / {} | ✅ |
PointerType | Int enum / 1 | PointerType | Int enum / 0 | ✅(默认不同) |
SectorAngle | Float / 90.0 | SectorAngle | number / 90.0 | ✅ |
PointerCount | Int / 1 | — | — | ❌ 缺(多指示器未支持) |
PointerOffsetAngle | Float / 0.0 | — | — | ❌ 缺 |
PointerIntervalAngle | Float / 0.0 | — | — | ❌ 缺 |
PointerOffset | Vector3 / [0,0,0] | — | — | ❌ 缺 |
ParabolaHorizontalSpeed | Float / 10.0 | ParabolaHorizontalSpeed | number / 10.0 | ✅ |
ParabolaVerticalSpeed | Float / 8.0 | ParabolaVerticalSpeed | number / 10.0 | ✅(默认不同) |
AnchorInfo(Map) | {} | AnchorInfos(数组,镜像字段) | {} | ⚠️ 形状不同(见 §锚点与时间轴对照) |
TimelineInfo(Map) | {} | TimelineInfos(数组,镜像字段) | {} | ⚠️ 形状不同 |
SubAbilities | Array<String> / [] | —(子技能组另有机制,未声明为属性) | — | ❌ 缺字段 |
SwitchMode | Int enum / 0 | — | — | ❌ 缺字段 |
SwitchOrder | Int enum / 0 | — | — | ❌ 缺字段 |
SwitchInterval | Float / 3.0 | — | — | ❌ 缺 |
SwitchCooldown | Float / 0.5 | — | — | ❌ 缺 |
RevertTime | Float / 0 | — | — | ❌ 缺 |
SwitchRefresh | Bool / true | — | — | ❌ 缺 |
| — | — | IsChargeConsuming 联动字段 ChargeInterval/MaxChargeCount/ChargeAmount | 作者版用 @visible_when 控制显隐 | ➕ 作者版可见性联动 |
运行时属性(不暴露到编辑面板)
官方属性(ability_type.lua) | 默认 | 作者版属性 | 状态 |
|---|---|---|---|
InCD | false | InCD | ✅ |
InCast | false | InCast | ✅ |
CdFinishTime | 0 | CdFinishTime | ✅ |
OwnerId | 0 | OwnerId | ✅ |
Index | 0 | Index(0 基,未入槽为 SLOT_INDEX_UNASSIGNED = -1) | ✅ |
AccumulateStartTime | 0 | AccumulateStartTime | ✅ |
ReleasePoint | [0,0,0] | ReleasePoint | ✅ |
ReleaseDirection | [0,0,1] | ReleaseDir | ⚠️ 命名不同 |
ReleaseTarget | 0 | ReleaseTarget | ✅ |
Level | 1 | Level | ✅ |
ChargeCount | 1 | ChargeCount | ✅ |
| — | — | CastStartTime | ➕ 作者版额外 |
| — | — | AccumulateRatio | ➕ 作者版额外(施法时捕获的蓄力比) |
| — | — | AbilityPresetKey | ➕ 作者版额外(运行时→资产回链) |
管理器属性
| 官方 AbilityManager | 作者版 ability_manager_script | 状态 |
|---|---|---|
InitAbilities Array<AbilityInfo> | InitAbilities List<ability_system.AbilityInfo> | ✅(元素字段名不同:AbilityAsset ↔ AssetId) |
IndexCounter Int | — | ❌ 缺(作者版用运行时 MaxSlotCount 属性 + DEFAULT_MAX_SLOT_COUNT=8) |
| — | Icon String(管理器图标) | ➕ 作者版额外 |
| 运行时/内部 | OwnerId、PlayerId、ManagerReady、MaxSlotCount | ➕ 作者版额外 |
事件对照
技能级事件
| 官方事件(Local/事件积木) | 作者版 BindableEvent 事件单位 | 状态 |
|---|---|---|
OnAbilityAdded | (管理器级 AbilityAdded) | ⚠️ 层级不同 |
OnAbilityRemoved | (管理器级 AbilityRemoved) | ⚠️ 层级不同 |
OnCastStart | CastStart | ✅ |
OnCastBreak | CastBreak | ✅ |
OnCastEnd(is_break) | CastEnd(二分:Break 独立事件,End 无 is_break 参数) | ⚠️ 结构不同 |
OnAccumulateStart | AccumulateStart | ✅ |
OnAccumulateBreak | AccumulateBreak | ✅ |
OnAccumulateEnd | AccumulateEnd | ✅ |
OnUpgrade | 管理器级 AbilityUpgraded | ⚠️ 层级不同 |
OnDowngrade | OnDowngrade | ✅ |
OnChargeEnd | ChargeFull(另有 Charge 层数变化) | ⚠️ 命名不同 |
OnAnchorStart/Break/Complete/End(声明但从未 Fire,见 §官方侧发现的存量问题) | AnchorStart / AnchorBreak / AnchorEnd / AnchorStop(真实触发) | ⚠️ 官方声明失效 |
| — | BeforeCast、BeforeUse、Used、CDStart、CDEnd | ➕ 作者版额外 |
管理器 / 子技能 / 锚点事件
| 官方 | 作者版 | 状态 |
|---|---|---|
| (无管理器事件积木) | AbilityAdded、AbilityRemoved、AbilityUpgraded、SwitchNext | ➕ 作者版额外 |
| 子技能组(内部) | OnActivated、OnDeactivated、OnSwitchNext | ➕ 作者版额外 |
动态 ABILITY_ANCHOR_BEGIN/BREAK/END/STOP_<GroupID> | 静态 AnchorStart/Break/End/Stop(载荷 abilityScript, groupId) | ⚠️ 机制不同 |
跨端 action 对照
| 官方 RemoteEvent | 作者版 RemoteEvent action(单通道 "AbilitySystem") |
|---|---|
c→s AddAbility | Cast(作者版客户端不直接请求添加技能) |
c→s RemoveAbility | — |
c→s AccumulateAbility | Accumulate |
c→s StopAccumulateAbility | — |
c→s CastAbility | Cast |
c→s StopAbility | BreakCast |
| — | Upgrade(声明,双端未接线) |
| — | SwitchNext |
s→c OnAccumulateStart/Break/End | 经 reactive 属性驱动 UI(无 action 分支) |
s→c OnCastStart/End | OnCastStart / OnCastEnd(作者版另有 OnCastBreak) |
s→c ForbidSlot | ForbidSlot |
| — | OnCDEnd、OnCharge、OnSwitchNext、FullSnapshot(预留) |
| — | 裸字符串 OnCDStart、AbilityAdded、AbilityRemoved、AbilityMoved |
另有组件级 RemoteEvent:
"BoxComponentCreated_" .. UnitId(box_component_create.lua/box_component_fix.lua),官方无。
枚举 / 常量对照
| 枚举 | 官方(code / meta) | 作者版(common/.../constants.lua) | 状态 |
|---|---|---|---|
PointerType | None=0/Rectangle=1/Circle=2/Sector=3/Parabola=4 | 同名同值 | ✅ |
TargetType | NoTarget=0/Direction=1/Point=2/Unit=3 | 同名同值 | ✅ |
ReleaseType | Release=0/Hold=1/TwoStage=2/Press=3 | 同名同值 | ✅ |
ChargeType | None=0/WhenNotFull=1/WhenEmpty=2 | 同名同值 | ✅ |
SwitchMode | None=0/AfterCast=1/Timer=2 | AfterCast/Timer/Manual(字符串;无 None) | ⚠️ 不同 |
SwitchOrder | Sequential/Shuffle/Random | 同名同值 | ✅ |
UseLimitation | None=0/InCast=1/UnControllable=2/Roll=4 | 同 + Freezed=8 | ⚠️ 多一位 |
TargetFilterType | meta 枚举 None/EggyUnit/HumanUnit/PhysicsUnit | 自由 String[](无枚举约束) | ⚠️ 不同 |
TargetFilterCamp | CampRelationType(外部类型)None=0/Enemy=1/Ally=2 | None=0/Enemy=1/Ally=2 | ✅ |
AbilityPhase | Accumulate=1/Cast=2(code-only,官方包内未使用) | anchor_script Phase 枚举 [[1 Accumulate],[2 Cast]] | ⚠️ 官方死枚举,作者版实际使用 |
Rarity | — | Common=1/Rare=2/Epic=3/Legendary=4 | ➕ 作者版额外 |
EventType / AnchorEvent / ManagerEvent | 分散在事件定义 | 集中收口于 constants.lua | ➕/差异 |
Tag | — | AbilityUnit / AbilityManager | ➕ 作者版额外 |
UIType | UI 节点定义在 ui.lua | AbilitySlot / AbilityAccumulateNode / AbilityCancelArea(custom_kv) | ⚠️ 机制不同 |
| 槽位常量 | — | SLOT_BASE=0、SLOT_INDEX_UNASSIGNED=-1、DEFAULT_MAX_SLOT_COUNT=8 | ➕ 作者版额外 |
锚点与时间轴对照
| 维度 | 官方 | 作者版 | 状态 |
|---|---|---|---|
| 锚点配置数据 | 资产顶层键 AnchorInfo = {GroupID: {StartTime, Duration, GroupID}},编辑权威 | 顶层键编辑 + 镜像到声明字段 AnchorInfos: [{GroupId, StartTime, Duration}](按 StartTime 升序) | ⚠️ 桥接 |
| 时间轴数据 | 顶层键 TimelineInfo = {1:{...},2:{...},11:[]} | 镜像 TimelineInfos: [{Phase, LineId, AdjustType}] | ⚠️ 桥接 |
| 锚点类 | common/anchor.lua:new/_RegisterEvent/BeginProcess/Start/Break/End/Complete/ClearTimer/_Callback/SendEvent/Destroy,自连 OnCastStart 后 Task:Delay 点火;回调在 config 字段 | common/Anchor.lua:new/_registerEvents/_connect/_fire/_clearTimers/beginProcess/start/finishCast/onBreak/finish/stop/Destroy,自订阅施法/蓄力信号 | ✅ 同构 |
| 锚点事件 | 动态名 ABILITY_ANCHOR_BEGIN/BREAK/END/STOP_<GroupID> + config 回调 | 静态事件单位 AnchorStart/AnchorBreak/AnchorEnd/AnchorStop(载荷 abilityScript, groupId) | ⚠️ 机制不同 |
| Phase | AbilityPhase:1 蓄力 / 2 施法 / 11 自定义 | 1 蓄力 / 2 施法(自定义 11 仅编辑侧) | ✅ |
| 锚点动作 | 无内置锚点类型(作者自己写回调) | 16 个内置锚点类型(anchor_scripts/*.lua 壳 + anchors/*.lua 逻辑),属性用 ABILITY_ANOSTATE_* 前缀 | ➕ 作者版额外,官方无等价 |
作者版 16 个锚点类型(每个锚点脚本壳声明 Icon/StartTime/Duration/Phase/TrackIndex + 自身 ABILITY_ANOSTATE_*/SPRING_ROPE_* 属性):
| 类型 | 说明 / 主要属性 |
|---|---|
active_cd | 强制进入 CD(无额外属性) |
add_bind_diy_model | 挂骨骼模型:ABILITY_ANOSTATE_USE_PERFAB、Socket、Offset |
bungee_cord | 弹簧绳:SPRING_ROPE_* 系列 11 项 |
cast_face_target | 施法者转向释放方向(无额外属性) |
create_bullet_to_castangle | 弹道子弹:ABILITY_ANOSTATE_BULLET_*、ABILITY_ANOSTATE_AREA/HITPOWER/NEW_SFX 等 |
create_landmine | 地雷:ABILITY_ANOSTATE_NEW_OBJ/OFFSET/SCALE/LIFE_DUR/... |
create_obstacle | 障碍物:ABILITY_ANOSTATE_NEW_OBJ/OFFSET/SCALE/BIND/LIFE_DUR |
create_teleportball | 传送球:BallDuration、ABILITY_ANOSTATE_BULLET_* |
custom_event | 触发自定义事件:ABILITY_ANOSTATE_EVENT_NAME |
destroy_ability | 销毁技能(无额外属性) |
gravity_change | 重力变化:ABILITY_ANOSTATE_UP_ACCELERATION |
melee_hit | 近战判定:ABILITY_ANOSTATE_HITBOX_*/HIT_SFX*/BULLET_DAMAGE/ANIMKEY/BINDSOCKET 等(存在键错配,见 §作者版 melee_hit 属性键错配) |
play_body_animation | 播放动画:ABILITY_ANOSTATE_ANIMKEY/ANIM_HALF/LOOP/ANIM_STARTPOINT/ANIM_SPEED |
play_sfx | 播放特效:ABILITY_ANOSTATE_NEW_SFX/OFFSET/SCALE/BIND |
play_vfx | 播放音效:ABILITY_ANOSTATE_NEW_SOUND、Volume、SoundDuration |
speed_add | 加速:ABILITY_ANOSTATE_WALK_SPEED |
扩展机制对照(Pointer / Strategy / Registry / UI)
| 机制 | 官方 | 作者版 | 状态 |
|---|---|---|---|
| 注册表 | common/registry.lua:Register/Get/GetAll | common/.../registry.lua:AbilityRegistry,含 ability/manager/group 反查 + 多态 domain + tag 封装 | ⚠️ 作者版更全 |
domain "PointerType" | ✅(controller.lua 注册 5 类) | ✅(Controller.lua 注册 5 类) | ✅ |
domain "ReleaseStrategy" | ✅ | ✅(Controller.lua 注册 4 类) | ✅ |
| 自定义 Pointer 接口 | new(ability, controller) + Create/Refresh/GetReleasePoint/Clear/Destroy | 同签名(Create(dirInfo)/Refresh(dirInfo)/GetReleasePoint(dirInfo)/Clear(dirInfo)/Destroy)+ UpdateEffect/UpdateTransforms/GetCameraRotation | ✅ |
| 自定义 Strategy 接口 | new(controller) + OnTouchBegin/OnTouchMove/OnTouchEnd/Destroy | 同(构造改为 setmetatable({ctrl=}, cls))+ TwoStage 额外 OnSceneClick/CancelAiming | ✅ |
| 注册入口 | Packages.ability_system.Register | AbilityClientAPI.Register(转发 Registry) | ✅ |
| UI 节点 | slot_node.lua / cancel_node.lua(+ ui.lua 属性声明) | AbilitySlot / AccumulateNode / CancelArea(custom_kv UIType) | ⚠️ 命名/机制不同 |
| UI 钩子 | 直接绑定 | common/.../ui_hooks.lua 占位层(no-op,UIManager 注入实现) | ➕ 作者版额外 |
| ECA 蛋码面 | api.lua 声明(不完整)+ meta JSON | eca.lua 65 积木 + 1 prefab 事件 | ➕ 作者版额外且完整 |
差异与缺口登记(重构待办候选)
按当前作者版相对官方的缺口:
- 属性缺口:
Name/Desc/Description、AccumulateFinishTime、PointerCount/PointerOffsetAngle/PointerIntervalAngle/PointerOffset(多指示器)、SubAbilities/SwitchMode/SwitchOrder/SwitchInterval/SwitchCooldown/RevertTime/SwitchRefresh(子技能组配置)、管理器IndexCounter。 - API 缺口:
GetAbilityByPrefab、ReplaceAbility、ForbidAbility、StopAccumulateAbility(独立包 API)、IsTargetType、GetIcon、GetDescription、GetReleasePointList/GetReleaseDirectionList、PickTargetInReleaseRange。 - 命名不一致:
ReleaseDir↔ReleaseDirection;AbilityInfo.AssetId↔AbilityAsset;ChargeFull↔OnChargeEnd;AnchorStop↔ 官方COMPLETE/STOP语义。 - 机制差异(设计决定,非缺陷):数据走 Attributes KV 而非 Unit 字段;事件走 BindableEvent 单位而非惰性 Signal;跨端走单通道 action 路由而非命名 RemoteEvent;锚点动作走 16 个内置类型而非 config 回调。
- 作者版额外能力(官方没有,非缺口):
BeforeCast/BeforeUse/Used/CDStart/CDEnd事件、管理器级事件、子技能组事件、AccumulateRatio/CastStartTime/AbilityPresetKey属性、ui_hooks占位层、16 个内置锚点类型、完整 ECA 面、Freezed限制位。
已知缺陷 / 契约风险
作者版 melee_hit 属性键错配(高优)
anchor_scripts/melee_hit.lua 声明的是 ABILITY_ANOSTATE_HITBOX_OFFSET / ABILITY_ANOSTATE_HITBOX_SCALE / ABILITY_ANOSTATE_HIT_SFX_SCALE / ABILITY_ANOSTATE_HIT_SFX_ROTATION / ABILITY_ANOSTATE_BULLET_HITSFXOFFSET / ABILITY_ANOSTATE_OFFSET / ABILITY_ANOSTATE_QUD / ABILITY_ANOSTATE_SCALE,而 anchors/melee_hit.lua 运行时读的是 HitboxOffset / HitboxScale / HitEffectScale / HitEffectRotation / HitEffectOffset / BindOffset / BindRotation / BindScale。壳声明名与运行时读取名不一致,配置面板填的值读不到。
作者版 ReleaseStrategy 方法名大小写错配(高优)
client/packages/ability_system/strategy/ReleaseStrategy.lua 调用 ctrl:_RequestAccumulate()(大写 R),但 Controller.lua 定义的是 _requestAccumulate(小写 r)。蓄力类技能(EnableAccumulate==true)会因 nil 调用而失败。
官方侧发现的存量问题(供重构时甄别,勿误当作者版回归)
doc/技能用户使用手册.md与代码不符:Icon类型(手册 Int / 代码 String)、CdTime(手册 Formula / 代码 Float)、TargetFilterType(手册 String / 代码 Array<String>)、缺Desc/Parabola*/TimelineInfo/AnchorInfo、缺PickTargetInReleaseRange/SetAbilityOwner;PointerType值 4 Parabola 未列。- 官方
api.lua声明不完整且含死声明:AddAbilityTest/CastAbilityTest未实现;漏GetAbilities/RemoveAbility/ReplaceAbility/GetAbilityByPrefab/AccumulateAbility/StopAccumulateAbility/BreakAccumulateAbility/ForbidSkillSlot/ActiveSkillSlot/ForbidAbility等。 - 官方
OnAnyAbilityAdded声明为 global 事件但包内无显式 Fire;OnAnchorStart/Break/Complete/End本地通道已声明但从未触发(实际用动态名ABILITY_ANCHOR_*_<GroupID>)。 - 官方
ability_manager.json(仅InitAbilities)与ability_manager_type.lua(含IndexCounter+ 方法与 hook)不一致;ability.json与ability_type.lua对EnableAccumulate/MaxAccumulateTime/AccumulateFinishTime的editable标记冲突。
附录:来源文件清单
官方:meta/data/ability.json、meta/unit/ability_type.lua、common/ability.lua、common/enums.lua、common/ability_event.lua、common/registry.lua、common/utils.lua、common/ability_manager.lua、common/anchor.lua、server/ability_system.lua、server/abilities/ability.lua、client/ability_system.lua、client/abilities/ability.lua、client/ui/controller.lua、api.lua、ui.lua、meta/enum/*.json、meta/data/ability_manager.json、meta/data/ability_info.json、meta/unit/ability_manager_type.lua、doc/技能用户使用手册.md。
作者版:server/packages/ability_system/{ability_script,ability_manager_script,ability_logic,ability_manager_logic,anchor_script,anchor_logic,sub_ability,api,eca}.lua、server/.../item_box/*、server/.../component_scripts/box_component_create.lua、server/.../anchors/(16)、server/.../anchor_scripts/(16)、common/packages/ability_system/{editor,data,constants,event_defs,registry,target_filter,util,ui_hooks,Anchor}.lua、client/packages/ability_system/{api,ability_local_script,ability_manager_local_script}.lua、client/.../ui/{UIManager,Controller,eui_adapter,scene_input}.lua、client/.../ui/nodes/{AbilitySlot,AccumulateNode,CancelArea}.lua、client/.../pointer/(5)、client/.../strategy/(5)、client/.../component_scripts/box_component_fix.lua。
