跳转至

技能编辑器

前期准备大纲

  • AGE文件(xml):类似于Timeline,存储技能编辑器信息
    • 时长
    • 循环
    • 参数列表,表现为key
    • 逻辑体:播age时可传入age参数
    • 程策约定的参数
    • 策划自定在Age的参数
    • 逻辑轨道
      • Tick:瞬时触发
      • Duration:持续触发
  • 基础接口
    • 定义变量
    • 赋值
    • Tick接口
    • Duration接口
    • 生成Pb代码(序列化)
  • 原子注释
  • 自定义注释(Odin自定义面板)

主动技能

框架

WeaponSkill:表示一个主动技能的实例(虽然命名带Weapon,但是跟武器没有太直接关系)

WeaponHelper:actor上的主动技能管理器

SkillPlayer:每个actor有一个,主要用于释放技能

BaseSkill:释放中的技能的实例

Skill:baseSkill的子类,所有的释放中的技能都是一个Skill,同时只能存在一个释放中的技能

NewSkill:无用,废弃的

CSkillInfo:运行时的技能配置类

SkillSlotInfo:槽位,展示在UI上的可以点击的

使用技能流程

  1. 每帧执行ControlHelper.ProcessInputCmd()函数,获取技能输入指令,调用SkillPlayer.UseSkill(skillId) 来释放指定的技能
  2. 技能的释放过程,实际上就是一个age的播放,技能开始,age开始,age播完,技能结束

技能配置结构

  1. 子弹列表:一个技能需要用到的所有子弹列表,AGE的EmitBullet里配一个下标,就会索引到这里的子弹id
  2. 技能对应Action:技能对应的age
  3. 槽位类型
  4. 技能效果列表:技能/子弹造成伤害时,通过索引在这里找到对应的伤害id

被动技能

框架

PassiveSkill:具体一个被动的实例

SkillHelper: actor身上的被动管理器

PassiveSkillManager: 主要是一些static的被动的条件的判断逻辑

PassiveEventListenerBase:被动监听器的基类

CPassiveSkillInfo:运行时的被动配置类

被动类型

  1. 由excel的字段SkillType和EventType决定
  2. SkillType为1:表示这个被动是一个常态的被动,即在角色出生、复活时会触发一次
  3. SkillType为2:表示这个被动是一个监听型的被动,监听到某个事件EventType后,触发一次;
  4. 如何新增?
    1. 被动类型跟CommandID对应(因为一些简单的被动,刚好就是监听对应的CommandID,所以用同一个枚举)
    2. 普通类型的被动:(以SkillHited为例子)
      1. 找到对应的CommandID,如CommandID.SkillHited表示技能命中的事件(如果没有对应的CommandID,则新增CommandID,并且在合适的地方DoCommand()触发这个事件)
      2. 针对这个这个新的事件,需要实现一个监听器,这里SkillHited的监听器为PassiveEventSkillHited,覆写OnEvent()函数,在里面做一些事件触发后的条件判断逻辑即可
    3. 复杂类型的被动
      1. 何谓复杂被动?一个简单的CommandID无法达到他的触发条件的即可以判断为复杂被动
      2. 这种复杂的被动,在CommandID里用2000以后的id来标识,它在PassiveSkill里单独实现注册逻辑,可以参考PassiveSkil.HitSamTargetEventCallback

被动触发效果

  • 播放AGE
  • 加Buff

被动条件

使用条件+参数完成

  • 新增条件判断
    • 枚举PASSIVE_CONDITIONAL_TYPE新增一项,
    • 然后在PassiveSkillManager里switch的逻辑里新增这个枚举的判断逻辑

子弹

框架

  • Bullet 为一个子弹的实例 (BulletBase是Bullet的子类,且没有其他继承,所以可以认为他两是一个类,不知为何这样设计)
    • 一个子弹的实例有其配置的参数(生存时间、距离、美术体、碰撞框、轨迹、跳转信息等等等等)
  • BulletFeatureBase 为子弹特性的基类,子弹的碰撞、分裂、反弹、轨迹均是特性
  • BulletCollider 碰撞特性,子弹造成伤害的逻辑都在这
  • BulletTrack 轨迹的基类 (最初设计上actor也能用轨迹),有相关的逻辑时机轨迹开始的Start、每帧更新移动逻辑的Motion、子弹被移除时候的OnRemove(一般不用写),与一些轨迹的通用工具函数
  • BulletBaseInspector 策划的轨迹参数配置面板,需要在这写上你的逻辑参数与中文备注

子弹碰撞

  • 目前除普通直线为快速子弹(联机时ds不生成该子弹,直接验证伤害)外,其他轨迹的子弹均为碰撞检测,与碰撞相关的逻辑修改可以查看Bullet.BCollider (BulletCollider类)
  • 联机时子弹的碰撞伤害由DS验证,所以轨迹的书写需要注意同步的逻辑

子弹轨迹

  • 主要是处理子弹不同的移动表现,抽象成一类轨迹,开放参数让策划进行配置
  • 一般来说关卡的轨迹只是移动的逻辑不同,因此新增轨迹类型尽量做成通用,但对于日后复杂的英雄技能与高级枪械的轨迹,专用轨迹则可以把一部分专用逻辑放在子弹的轨迹上面做
  • 类型
  • 新增轨迹脚本,继承BulletTrack类,在脚本与BulletCreateFactory几个固定函数注册一下 书写轨迹中需要的策划配置项 继承TrackData 书写具体的移动逻辑代码(专用轨迹可在其命中、死亡做逻辑),一般来说轨迹不需要控制子弹死亡和碰撞相关

技能系统Flow

  • Flow是一个可配置的流程图
  • Flow用于关卡和流程

使用

  1. 被动条件的监听
  2. 主动技能的分歧

技能系统的Flow

被动表的条件配置,只能支持一些简单的、通过代码实现好的条件 如果策划想要一些更加自由的功能,则可以让他们自己配flow来实现 * 被动表字段:flowPath * 一个被动最多对应一个flow * 对应代码中的字段:PassiveSkill中的FlowScriptController flow; * flow只能用于被动的条件,效果依旧时默认的加Buff,调AGE

主动技能分歧

比如近放狼,远放鹰

BUFF机制

概念

  • 时效性: 一定时间立即生效的效果,包含一般游戏定义的提升属性的增益和负面buff,但也能作为伤害、特效展示、层数标记等使用
  • 非永久:与被动概念的区别(其他游戏被动和buff可能仅时长不同)就是,被动一般为永久性,且仅充当监听触发buff,如一个永久+属性的被动,实际上是开局下发了一个无限时长的buff
  • 叠加性: buff可以根据不同层数叠加不同数值的某一效果

框架

BuffTemplateBase

  • 对应着概念所说的效果,是所有效果的基类
  • 效果逻辑 时机有 添加上时的OnActive、每帧更新的Process、移除时候的OnInActive(一般用于还原效果)

BufferObject

  • 代表着游戏场景中的一个buff实例,buff实例有其配置的buffID、效果(BuffTemplateBase)等
  • 运行时动态修改实例的持续时间、层数等,并触发对应的效果

BufferManager

  • 管理buff的添加、移除(在小队后台是否)、叠加等逻辑

XXXBuff :BuffTemplateBase

  • 具体生效的效果
  • 我们游戏的buff的效果目前没有多大的实现限制,但一般来说buff效果实现限制在buff持有者身上做逻辑,且buff效果逻辑在逻辑时机能够闭环的(比如打断其他buff,使得其他buff无法闭环,最好是类似装饰模式的思想),尽量避免有时序的bug

Buff的使用场景

以下简单举例需求的场景,欢迎持续补充! - 一个一次性的回血、掉血 or 在一定时间内持续性的回血 - 给怪播放一个一次性的爆炸特效 - 单纯用作其他技能系统的标记 or 作展示给玩家 - 增加XX属性、挂上XX状态 - 增伤 (造成伤害时会遍历buff) - 强制修改相机位置和大小