技能编辑器¶
前期准备大纲¶
- 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上的可以点击的
使用技能流程¶
- 每帧执行ControlHelper.ProcessInputCmd()函数,获取技能输入指令,调用SkillPlayer.UseSkill(skillId) 来释放指定的技能
- 技能的释放过程,实际上就是一个age的播放,技能开始,age开始,age播完,技能结束
技能配置结构¶
- 子弹列表:一个技能需要用到的所有子弹列表,AGE的EmitBullet里配一个下标,就会索引到这里的子弹id
- 技能对应Action:技能对应的age
- 槽位类型
- 技能效果列表:技能/子弹造成伤害时,通过索引在这里找到对应的伤害id
被动技能¶
框架¶
PassiveSkill:具体一个被动的实例
SkillHelper: actor身上的被动管理器
PassiveSkillManager: 主要是一些static的被动的条件的判断逻辑
PassiveEventListenerBase:被动监听器的基类
CPassiveSkillInfo:运行时的被动配置类
被动类型¶
- 由excel的字段SkillType和EventType决定
- SkillType为1:表示这个被动是一个常态的被动,即在角色出生、复活时会触发一次
- SkillType为2:表示这个被动是一个监听型的被动,监听到某个事件EventType后,触发一次;
- 如何新增?
- 被动类型跟CommandID对应(因为一些简单的被动,刚好就是监听对应的CommandID,所以用同一个枚举)
- 普通类型的被动:(以SkillHited为例子)
- 找到对应的CommandID,如CommandID.SkillHited表示技能命中的事件(如果没有对应的CommandID,则新增CommandID,并且在合适的地方DoCommand()触发这个事件)
- 针对这个这个新的事件,需要实现一个监听器,这里SkillHited的监听器为PassiveEventSkillHited,覆写OnEvent()函数,在里面做一些事件触发后的条件判断逻辑即可
- 复杂类型的被动
- 何谓复杂被动?一个简单的CommandID无法达到他的触发条件的即可以判断为复杂被动
- 这种复杂的被动,在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用于关卡和流程
使用¶
- 被动条件的监听
- 主动技能的分歧
技能系统的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) - 强制修改相机位置和大小