资讯详情

ET 技能与 Buff 系统包 cn.etetet.spell 全面解析:配置模型、运行时施法链路与编辑器工具链

📅 2026/9/16 17:15:26 | 华诺云谱 👁 阅读
ET 技能与 Buff 系统包 cn.etetet.spell 全面解析:配置模型、运行时施法链路与编辑器工具链
ET 技能与 Buff 系统包 cn.etetet.spell 全面解析配置模型、运行时施法链路与编辑器工具链【免费下载链接】ETUnity3D Client And C# Server Framework项目地址: https://gitcode.com/GitHub_Trending/et/ET导读cn.etetet.spell是 ET 框架Unity3D Client And C# Server Framework中负责**技能Spell与 Buff增益/减益状态**的完整功能包涵盖 Spell/Buff 配置模型、服务端运行时施法逻辑、客户端表现组件以及配套的 Unity 编辑器工具。本文以Packages/cn.etetet.spell/AGENTS.md为骨架结合该包源码Scripts/Model、Scripts/Hotfix、Scripts/HotfixView、Scripts/Editor与配置资产系统讲解技能/Buff 的数据模型与配置方式、服务端施法与 Buff 生命周期管理、效果节点与行为树驱动的实现原理、客户端表现与消息同步以及 Spell Editor 编辑器工具的使用与开发约束最终帮助你在自己的 ET 项目中落地一套可复用的技能系统。包概览定位、依赖与目录结构cn.etetet.spell的定位由 AGENTS.md 概述为技能与 Buff 系统包包含四大部分Spell/Buff 配置模型——配置数据结构与代码生成运行时施法逻辑——服务端施法、目标选择、消耗与 CD 管理客户端表现组件——技能指示器、Buff 表现物体等spell 相关 Unity 编辑器工具——Spell Editor 窗口及资产导出链路。包的版本与依赖定义在 package.json版本 4.0.0Unity 2022.3核心依赖包括cn.etetet.core实体组件基础框架cn.etetet.configLuban 配置生成cn.etetet.proto协议代码生成cn.etetet.behaviortree行为树用于目标选择/消耗/效果节点cn.etetet.numeric数值组件Buff 修改数值的底层支持cn.etetet.unit、cn.etetet.map、cn.etetet.yooassets、cn.etetet.yiuiframework等。从 目录结构 可以看出包内代码按 ET 标准分层Scripts/ ├── Model/ # 纯数据结构Buff/SpellConfig、EffectNode、CostNode、TargetSelector、各 Component ├── Hotfix/ # 逻辑层 │ ├── Share/ # 双端共享BuffSystem、BuffComponentSystem、SpellComponentSystem、BuffTickComponentSystem │ ├── Server/ # 服务端SpellHelper.Cast、BuffHelper、伤害/仇恨/数值记录等 │ ├── Client/ # 客户端SpellHelper、BuffHelper、消息 HandlerM2C_BuffAdd 等 │ └── Test/ # Fiber 单测Spell_FiberSingleton_Test ├── HotfixView/ # 客户端表现BuffGameObjectComponentSystem、SpellIndicatorComponentSystem、TargetSelector ├── ModelView/ # 客户端表现数据结构BuffScriptableObject、SpellScriptableObject └── Editor/Share/ # SpellEditor 工具编译进 ET.EditorSpell 配置模型SpellConfig 与配置表生成SpellConfig 字段详解Spell 的主配置类型为 SpellConfigScripts/Model/Share/SpellConfig.cs它继承Object并使用 Odin 特性组织 Inspector 布局字段Odin 标注含义IdReadOnlyBoxGroup(技能信息)技能 ID主技能 ID 为 10 的整数倍见下文 ID 分组规则DescBoxGroup(技能信息)技能描述IconNameBoxGroup(技能信息)技能图标资源名CDBoxGroup(技能信息)技能 CD单位毫秒intDamageMultiplierBoxGroup(技能信息)默认 100伤害系数百分比默认 100%CostLabelText(消耗)消耗节点CostNode行为树驱动TargetSelectorLabelText(目标选择)目标选择器TargetSelector行为树驱动同文件中还定义了CastTimeType枚举标注三种施法类型[LabelText(施法类型)] public enum CastTimeType { [LabelText(普通攻击)] Attack, [LabelText(读条)] Cast, [LabelText(吟唱)] Channeling, }SpellConfigCategory单例配置表SpellConfigCategory 是一个SingletonIConfig的配置表容器标记[ConfigProcess(ConfigType.Code)]内部用Dictionaryint, SpellConfig _dataMap按 Id 索引提供Get / Contain / GetAll / Add接口并在加载后统一调用ResolveRef()完成引用解析。对应的代码生成产物位于 CodeMode/Config按 Client / ClientServer / Server 三种 CodeMode 分别生成。配置数据源是 Luban 的 Excel 表Luban/Config/Base/tables.xlsx 等Luban/Config/Base下还有__beans__.xlsx、__enums__.xlsxLuban/Config/Datas下有Text.xlsx。因此修改 Spell/Buff 配置字段后需要通过 Luban 链路重新生成配置代码与二进制数据。技能 ID 分组规则与“主/子技能”SpellEditorConstants.cs 定义了技能与 Buff 资产的核心编号约定public const int SpellGroupSize 10; public static bool IsMainSpell(int id) id % SpellGroupSize 0; // 主技能 public static bool IsSubSpell(int id) id % SpellGroupSize ! 0; // 子技能 public static int MainSpellBase(int spellId) spellId / SpellGroupSize * SpellGroupSize;即每个主技能占用连续 10 个 ID如 100100主技能本身是 10 的整数倍其余 9 个 ID 留给它的子技能Buff。这一规则同时体现在运行时的BuffSystem.GetSpellConfigId()见下文也是 SpellEditor 资产命名s{spellId}/b{buffId}与导出工具解析的基础。Buff 配置模型BuffConfig、BuffFlags 与效果节点BuffConfig 字段详解Buff 的主配置类型为 BuffConfigScripts/Model/Share/BuffConfig.cs同样通过 Odin 布局字段默认值含义Id—ReadOnlyBuff 配置 ID通常与所属主技能 ID 同段Desc—描述Duration1000000000持续时间毫秒。注意默认值极大等价于“近乎永久”配置为负数时运行时按“无到期时间”处理ExpireTime long.MaxValueTickTime0Tick 间隔毫秒0 时启用周期效果MaxStack1最大叠加层数Stack1初始层数OverLayRuleType—叠加规则类型见下Flags空移除条件集合BuffFlagsNoticeType—广播客户端类型NoticeTypeEffects空列表效果节点列表EffectNode可多选其中Effects在 Unity 下用[UnityEngine.SerializeReference]序列化并维护一个DictionaryType, EffectNode effectDict缓存OnBeforeSerialize/OnAfterDeserialize时重建提供GetEffectT()按类型快速取效果节点——这是运行时buff.GetConfig().GetEffectEffectServerBuffAdd()一类调用的底层支撑。OverLayRuleType定义四种叠加规则public enum OverLayRuleType { [LabelText(无)] None, // 不叠加 [LabelText(层数)] AddStack, // 叠加层数 [LabelText(时间)] AddTime, // 刷新/延长持续时间 [LabelText(替换)] Replace, // 相同配置 ID 直接替换 }BuffFlags移除条件集合BuffFlags.cs 定义了 Buff 的 17 种移除条件含 None0是 Buff 生命周期管理的核心语义Flag含义TimeoutRemove超时删除DeadRemove死亡删除InBattleRemove/OutBattleRemove进入/离开战斗删除MoveRemove移动删除DamageRemove受伤删除CurrentSpellRemoveRemove当前技能删除时一并删除RideRemove骑乘删除StackRemove层数归零删除SameConfigIdReplaceRemove相同配置 ID 替换NewSpellInterrupt新技能打断NoDurationRemove无持续时间删除ParentRemoveRemove父 Buff 移除时随删用于技能→子 Buff 的绑定NotFoundTargetRemove目标不存在删除StunRemove眩晕删除AIRemoveAI 删除这些 Flag 同时用于BuffComponent.flagBuffs的索引见下文实现“按 Flag 批量查/删 Buff”。效果节点体系EffectNodeEffects列表中每一项都是抽象类EffectNode的派生类。EffectNode.cs 定义EffectNode : BTRoot——效果节点本身就是一个行为树根节点BTRoot这决定了“Buff 效果由行为树驱动”的实现方式。包内预置的效果节点均在Scripts/Model/Share/下节点触发时机EffectServerBuffAddBuff 创建InitBuff 时执行EffectServerBuffRemoveBuff 移除RemoveBuff 时执行EffectServerBuffTick周期 TickBuffTickComponent 每次 OnTick 执行EffectServerBuffHitted被击中时执行EffectClientBuffAdd/EffectClientBuffRemove/EffectClientBuffHitted客户端对应的表现/逻辑效果服务端在InitBuff/RemoveBuff/OnTick中分别通过GetEffectEffectServerBuffAdd()等取出节点用BTEnv绑定Buff、Unit、Caster上下文后BTHelper.RunTree驱动执行源码见 BuffHelper.cs 与 BuffTickComponentSystem.cs。CostNode消耗节点CostNode.cs 定义技能消耗的行为树节点同样是BTRoot声明三个BTOutput输出参数public class CostNode: BTRoot { [BTOutput(typeof(Buff))] public string Buff Buff; [BTOutput(typeof(Unit))] public string Unit Unit; [BTOutput(typeof(bool))] public string Check Check; }运行时会先以Check true跑一次做“消耗检查”通过后再以Check false跑一次真正扣减见下文施法流程。运行时数据模型Buff、BuffData 与索引组件Buff 实体Buff.csScripts/Model/Share/Buff.cs是运行时的 Buff 实体[ChildOf(typeof(BuffComponent))]挂载在 Unit 的BuffComponent下[ChildOf(typeof(BuffComponent))] public class Buff: Entity, IAwakeint, IDestroy { public int ConfigId; // Buff 配置 ID public long Caster; // 施法者 Unit Id public long CreateTime; // 创建时间ServerNow public int TickTime; // 实际生效的 Tick 间隔 public long ExpireTime; // 到期时间 public int Stack; // 当前层数 public long TimeoutTimer; // 到期一次性定时器 [BsonIgnore] public EntityRefBuffData BuffData; // Buff 上下文 }BuffData不被销毁的 Buff 上下文BuffData.cs 注释明确其为“buff上下文不会被dispose”用来在 Buff 生命周期之外保存跨阶段数据如施法目标SpellTargetComponentParentData指向父 Buff 的 BuffData形成父子链[ComponentOf(typeof(Buff))] public class BuffData: Entity, IAwake { public EntityRefBuffData ParentData; }BuffSystem.GetBuffData()BuffSystem.cs在Buff.BuffData为空时自动AddComponentBuffData()创建而移除 Buff 时只RemoveComponentBuffData(false)显式保留 BuffData 供数据传递见BuffComponentSystem.RemoveBuff中注释“BuffData靠GC回收方便传递数据”。BuffComponent三套索引BuffComponent.cs 挂载在 Unit 上[ComponentOf(typeof(Unit))]用三张MultiMapSet索引当前全部 BuffflagBuffskey BuffFlags支持按移除条件批量查询如“移除所有 MoveRemove 的 Buff”effectBuffskey EffectNode 的 Type支持按效果类型查询configIdBuffskey BuffConfig.Id支持按配置 ID 查询/叠加判定。对应查询/删除 API 在 BuffComponentSystem.csHasBuff(configId)、GetByFlag(flag)、GetByConfigId(configId)、GetOneByConfigId(configId)、GetByEffectTypeT()CreateBuff(buffId, buffConfigId, casterId)创建时同步写入三套索引并按Duration 0决定ExpireTime long.MaxValueRemoveBuff(buff)反向清理索引RemoveComponentBuffData(false)保留上下文后移除子实体。SpellComponentCD 与技能修改点SpellComponent.csScripts/Model/Share/SpellComponent.cs同样挂载在 Unit 上维护Current当前正在施放的 Buff技能本体以 Buff 形式存在CDTime公共 CD 时间点SpellCDDictionaryint, long每个技能 ID 的 CD 时间点SpellModsDictionaryint, Dictionaryint, int技能修改点按 SpellModType 索引的整型数值累加用于天赋/Buff 对技能伤害、持续时间、施法时间、范围等的动态修正。SpellComponentSystem.cs 提供CheckCD公共 CD 500ms 技能自身 CD、UpdateCD、GetMod、AddMod等接口。SpellModType枚举同文件定义了 40 余种修改点如SPELLMOD_DAMAGE(10)、SPELLMOD_DURATION(11)、SPELLMOD_THREAT(12)、SPELLMOD_RANGE(15)、SPELLMOD_CASTING_TIME(20)、SPELLMOD_COOLDOWN(21)、SPELLMOD_GLOBAL_COOLDOWN(31)等与经典魔兽式技能模板的修改点模型同构。服务端施法链路SpellHelper.Cast 与技能本体即 Buff服务端施法入口是 SpellHelper.csScripts/Hotfix/Server/SpellHelper.cs核心思想是**“技能本体以 Buff 形式存在”**一次施法 创建一个带完整上下文的主 Buff并驱动其生命周期。public static int Cast(Unit unit, int spellConfigId, Buff parent null) { SpellConfig spellConfig unit.Fiber().GetSingletonSpellConfigCategory().Get(spellConfigId); SpellComponent spellComponent unit.GetComponentSpellComponent(); // 1. 检查主技能才检查 CD子技能/附带技能跳过 if (SpellConfigHelper.IsMainSpell(spellConfigId)) { bool ret spellComponent.CheckCD(spellConfig); if (!ret) return TextConstDefine.SpellCast_SpellInCD; } // 2. 创建技能本体 Buff Buff buff BuffHelper.CreateBuffWithoutInit(unit, unit.Id, IdGenerater.Instance.GenerateId(), spellConfig.Id, parent); int castRet SpellCasting(unit, buff, spellConfig, parent); if (castRet ! 0) unit.GetComponentBuffComponent().RemoveBuff(buff); // 失败则回收 return castRet; }另有重载Cast(unit, spellConfigId, Unit target, Buff parent null)在创建 Buff 后向buff.GetBuffData()添加SpellTargetComponent并写入目标 Unit Id绕过后续的目标选择步骤。SpellCasting私有核心方法依次完成打断当前技能无父 Buff 时若spellComponent.Current存在则BuffHelper.RemoveBuff(currentBuff, BuffFlags.NewSpellInterrupt)并把新 Buff 设为Current目标选择若 BuffData 上没有预置的SpellTargetComponent则读取spellConfig.TargetSelectorBTRoot用BTEnv注入Buff/Caster/Owner后BTHelper.RunTree执行失败则返回错误码消耗检查与扣除spellConfig.CostCostNode先以Checktrue运行做资源检查再以Checkfalse运行实际扣减更新 CDspellConfig.CD 0时UpdateCD(unit, spellConfig.Id, ServerNow)初始化 BuffBuffHelper.InitBuff(buff)进入 Buff 生命周期若buff.ExpireTime ServerNow无持续时间的即时技能立即以BuffFlags.NoDurationRemove移除。UpdateCD在 Unit 为UnitType.Player时还会下发M2C_UpdateCD消息通知客户端刷新 CD 表现。从网络入口到施法的链路客户端通过 Spell_C_10200.proto 定义的C2M_SpellCast字段含SpellConfigId、TargetPosition、TargetUnitId发送请求服务端 C2M_SpellCastHandler.cs 收到后调用SpellHelper.Cast客户端侧 SpellHelper.cs 仅负责把C2M_SpellCast通过ClientSenderComponent发往服务端。Buff 生命周期管理创建、叠加、Tick、移除创建与初始化InitBuffBuffHelper.cs 的CreateBuff/CreateBuffWithoutInit/InitBuff构成 Buff 创建链路。CreateBuffWithoutInit只做创建与父子绑定若父 Buff 带ParentRemoveRemoveFlag则挂到BuffChildrenComponent下随父删除CreateBuff额外调用InitBuff。InitBuff的完整流程处理叠加规则OverLayRuleType通过GetByConfigId找到同类旧 Buff——AddStackUpdateStack(oldBuff, oldBuff.Stack buffConfig.Stack)并返回旧 BuffAddTimeexpireTime比旧 Buff 更晚才刷新防止“越叠越短”Replace移除同配置旧 BuffSameConfigIdReplaceRemove刷新 Tick 组件TickTime 0时挂载BuffTickComponent注册到期定时器ExpireTime有效0 long.MaxValue时NewOnceTimer(ExpireTime, TimerInvokeType.BuffTimeoutTimer, buff)执行 Add 效果GetEffectEffectServerBuffAdd()用 BTEnv 执行广播客户端构造M2C_BuffAdd携带BuffId / BuffConfigId / CreateTime / TickTime / ExpireTime / Stack / CasterId / SpellTarget按buffConfig.NoticeType下发。周期 TickBuffTickComponentSystem.cs 实现周期效果Awake时读取EffectServerBuffTick若Override true则挂载到 Unit 的BTCoroutineComponent并AddAI(buff)即 Tick 期间覆盖该 Unit 的 AI 行为如吟唱引导型技能Destroy时ResumeAI()Start()立即执行一次OnTick()随后NewRepeatedTimer(tickTime, TimerInvokeType.BuffTickTimer, self)循环OnTick()再次BTHelper.RunTree(EffectServerBuffTick)执行每次 Tick 的效果如流血/回蓝。移除RemoveBuff(buff, removeType)的执行序列构造M2C_BuffRemove→ 挂载/写入BuffRemoveTypeComponent记录移除原因 → 执行EffectServerBuffRemove→BuffComponent.RemoveBuff(buff)清理索引 → 按NoticeType广播客户端。配套的批量移除 API 包括RemoveBuff(unit, long id, BuffFlags)按 Buff 实例 IDRemoveBuffByConfigId(unit, configId, BuffFlags)按配置 ID 批量RemoveBuffFlag(unit, flag)/RemoveBuffsByFlag(unit, flag, removeType)按 Flag 批量。BuffFlags.TimeoutRemove由BuffTimeoutTimerATimerBuff同样定义在 BuffHelper.cs 中在到期时自动触发。动态更新与客户端同步UpdateStack限制在MaxStack内归零时以StackRemove移除UpdateExpireTime重建到期定时器防止过期则立即移除UpdateTickTime动态改变 Tick 间隔并刷新 Tick 组件。三者都会构造M2C_BuffUpdate广播客户端。对应的客户端消息 Handler 位于Scripts/Hotfix/Client/M2C_BuffAddHandler.cs、M2C_BuffRemoveHandler.cs、M2C_BuffUpdateHandler.cs、M2C_UpdateCDHandler.cs。Buff 与技能的联动Buff 修改数值与技能修改点BuffChangeNumericRecordComponent.cs 与对应 System 负责记录并回滚 Buff 对 Unit 数值组件cn.etetet.numeric的修改保证 Buff 移除后数值能正确还原BuffSpellModRecordComponent.cs 与对应 System 记录 Buff 对SpellComponent.SpellMods的修改移除时回滚技能修改点ThreatComponent.cs 与ThreatInfo.cs提供仇恨累积支持与SpellModType.SPELLMOD_THREAT对应DamageHelper.cs、DamageEvent.cs 提供伤害结算与伤害事件供NumericChange_DamageRemoveBuff.cs、ChangePosition_RemoveBuff.cs这类“条件触发移除”使用——前者在数值变化受击时移除DamageRemove类 Buff后者在位移时移除MoveRemove类 Buff。这一设计与SpellModType40 种技能修改点共同支撑起“天赋/Buff 动态改技能、技能释放改数值、受击/位移触发清 Buff”的完整联动闭环。客户端表现组件技能指示器与目标选择SpellIndicatorComponent.cs 与 SpellIndicatorComponentSystem.cs技能释放前的范围/方向指示器表现TargetSelector.cs、TargetSelectorCircle.cs/TargetSelectorPosition.csScripts/Model/Share/Root/定义目标选择器节点TargetSelectDispatcher.csScripts/Model/Client/负责客户端按需分发HotfixView/Client/TargetSelector/下提供圆范围选择TargetSelectorCircleHandler与点位置选择TargetSelectorPositionHandler的视图处理。Buff 表现BuffGameObjectComponent.cs 与 BuffGameObjectComponentSystem.cs将 Buff 绑定到具体 GameObject 表现SpellScriptableObject.cs / BuffScriptableObject.cs客户端可编辑的技能/Buff ScriptableObject 资产。Spell Editor 编辑器工具链入口与主界面SpellEditor 是包内自带的 Unity 编辑器窗口入口在 SpellEditorWindow.cs[MenuItem(SpellEditorConstants.MenuPath)] // ET/Spell/Spell Editor public static void Open() { ... }窗口顶栏提供三个核心按钮刷新重建资产索引保存SpellEditorAssetOperations.SaveAssets()保存当前编辑的资产导出配置SpellEditorAssetOperations.ExportConfig()走现有的 ScriptableObject 导出链路对应 AGENTS.md 中“导出 Spell/Buff 配置时复用现有 ScriptableObject 导出链路”的规则。主界面分为主技能列表可调宽度面板、资产工具栏与技能/ Buff 表格区支持技能筛选、重命名、复制主技能等功能见 SpellEditorWindow.cs 字段mainSpellFilter、renameId、copyMainSpellId等。资产组织与命名约定SpellEditorConstants.cs 定义资产根目录与命名规则资产根目录BtAssetRoot Packages/cn.etetet.statesync/Assets/BT对应 AGENTS.md 中“当前资产来源为Packages/cn.etetet.statesync/Assets/BT/**”命名前缀技能资产s{spellId}兼容旧前缀SpellBuff 资产b{buffId}兼容旧前缀Buff提供TryParseSpellAssetName / TryParseBuffAssetName从资产名反解 ID。编辑器目录下还包含SpellEditorAssetIndex.cs资产索引SpellEditorGraphBuilder.cs效果/消耗/目标选择节点图构建SpellEditorReference.cs 与 SpellEditorReferenceScanner.cs资产引用扫描SpellEditorValidator.cs配置校验产出SpellEditorIssue问题列表SpellEditorModels.cs 与 SpellEditorEffectsPopupContent.cs界面数据模型与效果节点选择弹窗。开发规则与工程约束AGENTS.md 逐条解读AGENTS.md 列出的开发规则既是本包作者的工作约定也是理解工程结构的钥匙遵守根目录 AGENTS.md 与Packages/cn.etetet.harness/AGENTS.md本包开发受 AGENTS.md仓库根与 harness 包说明 的全局规范约束所有命令必须使用pwsh本仓库的构建/导出/测试脚本如 Scripts 目录 下的 PowerShell 脚本均以 PowerShell 为准C# 文件默认一类一文件与Scripts/Model|Hotfix|ModelView|HotfixView各子目录下文件组织方式一致新增编辑器代码放在Scripts/Editor/Share/下编译进ET.Editor本包的编辑器工具全部位于Scripts/Editor/Share/SpellEditor/不手工创建.meta由 Unity 刷新生成、不手工修改.csproj修改 Spell/Buff 配置源时当前资产来源为Packages/cn.etetet.statesync/Assets/BT/**Spell/Buff 的行为树资产实际存放在 statesync 包的Assets/BT下对应SpellEditorConstants.BtAssetRoot导出 Spell/Buff 配置时复用现有 ScriptableObject 导出链路对应 SpellEditor 的“导出配置”按钮实现。测试验证Fiber 单测示例包内自带一个 Fiber 级测试 Spell_FiberSingleton_Test.cs它验证了 Spell/Buff 配置表在 Fiber 单例中的使用方式也示范了如何在测试中注入 Mock 配置await using TestFiberScope scope await TestFiberScope.Create(context.Fiber, SceneType.TestCase, nameof(Spell_FiberSingleton_Test)); Fiber robot await TestHelper.CreateRobot(testFiber, Client); Unit unit TestHelper.GetServerUnit(testFiber, robot); SpellConfig globalSpellConfig unitFiber.GetSingletonSpellConfigCategory().Get(100100); BuffConfig globalBuffConfig unitFiber.GetSingletonBuffConfigCategory().Get(globalSpellConfig.Id); // 构造 Mock 配置并替换 Fiber 单例 unitFiber.AddSingleton(mockSpellCategory); unitFiber.AddSingleton(mockBuffCategory); Buff buff buffComponent.CreateBuff(IdGenerater.Instance.GenerateId(), mockBuffConfig.Id, unit.Id);要点主技能100100必然对应同名 Buff 配置印证“技能本体即 Buff”通过unitFiber.AddSingleton(...)在测试 Fiber 内替换SpellConfigCategory/BuffConfigCategory单例即可隔离测试数据无需改动全局配置。总结技能系统的整体工作流把以上各节串起来一次完整技能交互的链路是客户端发出C2M_SpellCastSpellConfigId TargetPosition TargetUnitId必要时先播放技能指示器SpellIndicatorComponent服务端C2M_SpellCastHandler→SpellHelper.Cast校验 CD → 创建技能本体 Buff → 打断旧技能 → 行为树目标选择TargetSelector→ CostNode 检查/扣除 → 更新 CD →InitBuffBuff 生命周期BuffComponent建索引 → 按OverLayRuleType处理叠加 → 注册到期定时器 → 执行EffectServerBuffAdd→ 按NoticeType下发M2C_BuffAdd运行期BuffTickComponent周期执行EffectServerBuffTickDOT 类效果EffectServerBuffHitted响应受击Buff 通过BuffChangeNumericRecordComponent/BuffSpellModRecordComponent修改数值与技能修改点移除到期TimeoutRemove、受击DamageRemove、位移MoveRemove、层数归零StackRemove、新技能打断NewSpellInterrupt、父 Buff 删除ParentRemoveRemove等任一 Flag 触发 → 执行EffectServerBuffRemove→ 清理索引与数值回滚 → 下发M2C_BuffRemove客户端通过M2C_BuffAdd/Update/RemoveHandler 同步表现BuffGameObjectComponent驱动具体 GameObject 特效。借助这套“配置Luban 表 SpellEditor 资产 行为树效果节点 实体组件运行时”的组合cn.etetet.spell为 ET 项目提供了一套可配置、可扩展、逻辑与表现分离的完整技能/Buff 框架而Scripts/Hotfix/Test/Spell_FiberSingleton_Test.cs则为后续扩展提供了可直接照搬的验证范式。【免费下载链接】ETUnity3D Client And C# Server Framework项目地址: https://gitcode.com/GitHub_Trending/et/ET创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。