找到ECS实现增益减益系统的最佳方法

林一二2025年01月05日 17:00
  1. 影响属性值,各个别的系统要取属性值,如何解耦
    1. 如果允许带多个同名组件(很少有,一般是用列表存储),可以让增益直接添加一个属性组件,取属性的地方取所有同名属性组件然后把数值加起来。好处是不需要处理撤销影响。缺点是有的新人可能会忘了在助手方法里计算新加的增益
    2. 分为核心属性和临时属性,临时属性随便修改,然后通过助手方法加起来。本质上是缓存了对一大堆增益的加和计算。如果临时属性有多种,那么称为属性池。由于是各个增益在生命周期里修改临时属性并记录具体值(防止扣除时的百分比问题),协作时不容易出问题。
      1. 属性字段定义是本体,策划定义的是静态资源(本体的实例),运行时计算的是动态资源,可能会有多个动态资源为一个本体字段服务,加总后才相当于一个策划定义的字段
  2. 影响战斗效果,或无敌取消战斗效果
    1. 让战斗系统等识别最关键的5个抽象component,其他增益视为他们的子类或者是添加这些
      1. Stun(眩晕状态——目标不再响应任何操控)
      2. Root(缠绕,又称定身——目标不响应移动请求,但是可以执行某些操作,如施放某些技能)
      3. Silence (沉默——目标禁止施放技能)
      4. Invincible (无敌——几乎不受到所有的伤害和效果影响)
      5. Invisible (隐身——不可被其他人看见)
  3. 增益取消时,需要撤销影响
    1. 很多人还是把增益做成有生命周期的对象,而不是完全遵循ECS,因此移除时要调用生命周期方法,或者监听移除事件并调用。这样其实可以称为「子状态」而不是增益
    2. 如果这样的话,技能效果、AOE区域也可以看做对象甚至是持有时间轴的状态机,在ECS里很多组件就可以是状态机
      1. 这样其实类似分层状态机,ECS World 就是一个全局的状态,各个系统用低耦合的方式写状态转移,而只有特定的状态下才需要考虑增益这些子状态机。分层状态机的特点就是不需要时刻考虑所有状态,有的状态机只在特定状态下才会运行。
      2. 可以在各系统里只给这些状态机发消息,它们自己决定要怎么转移状态,以及进入各状态时的操作,这样也方便可视化编辑状态和看到迁移过程,不关心特定回调点的增益会直接无视信号,就像关联数据就像一袋薯片中说的一样。不过增益用不到状态机,用触发(回调、生命周期)就够了,实时游戏的技能才用得到状态机。
    3. 还需要监听很多别的事件,可以在别的系统里调增益对象的生命周期,在每个生命周期系统里遍历所有增益调用它们的某个生命周期方法;也可以让每个增益由一堆无状态的方法来实现,状态用自己特有的组件来存储;
      1. 角色攻击受击击杀死亡增益加减都通过信号组件来声明式地添加,然后在之后执行的系统里处理,这样就可以在处理普通行为的系统之前插入调用增益生命周期方法的系统
      2. 信号量也作为API使用,各增益和技能会读取这些信号,并添加修改后的信号
    4. 组件不能仅是标志,而需要是引用计数,这样多个无敌增益才不会一个消失就让玩家失去无敌

参考

ECS技能系统学习 开发游戏

Undefined widget 'supertag-form'