游戏技能实现的三种方式:
1.类似UE中GAS的方式,统一为Ability,并且不处理任何数据逻辑。
https://github.com/No78Vino/gameplay-ability-system-for-unity
2.类似双影其境那种, 简单直观,每个Ability都是独立处理响应、行为。
3.一个SkillController方式。 SkillController驱动所有Skill的更新,Skill+Buff系统去处理战斗内每个Entity的行为。
其实类似第1中方式。不过没有这么明确的限定“属性”一定要在GAS中的GameEffect中进行处理
主要目标:本文讨论第3种的实现方式的实现思路。本文并没有讨论“属性”的实现,没有讨论editor实现。
第一步:有哪些内容需要实现?
1.触发器
一个triggerCondition可以触发 triggerActionList
一个Skill可以有多个triggerConditionList
2.每个skill的状态和具体逻辑,和触发后的逻辑;
skill的Active状态,skill在Active状态下内部逻辑
3.每个skill之间的关系。
比如当active skillA的时候 会禁用skillB。
比如有active skillA的时候,不能active skillB
4.多个skill绑定ownerEntity
第二步:怎么实现
so : ScriptableObject的缩写
我们定义了一个SkillContainer的So,里面包含了所有信息。
1. 一个triggerCondition只是condition,并不关心触发后的triggerActionList是什么。我们使用组合的方式
1.1 triggerCondition是一个so
1.2 triggerActionList的element是so (eventData)。
像一些CommonAction由指定CommonActionSystem去监听执行,比如常见的消耗、发射单发子弹行为。
像一些特殊的Action由当前skill.cs去执行。比如 每隔1s生成一颗环绕的旋转球
在实现skill流程后,通过配置去映射流程的实现, 并且,配置去“配”一些通用的功能。
2.skill的话需要定义
2.1
interface ISkill
{
bool Active { get; set; }
bool TryActivate();
void Deactivate();
void Tick();
}
2.2 trigger的action直接监听1.2中的 triggerActionEventData
2.3 针对快节奏的项目,而非大世界的项目。我觉得直接把所有skill看作permanentSkill就行了,如果不需要了,直接Deactive。
如果是战斗内new的skill,也没有问题。
最多在Deactive的时候,把可能的“大数据”给clear或者returnPool。
这样比较简单直接
3.skill之间的关系
当整体skill流程完成后,通过skill内的tag数据去做“流程内”的细节处理。
比如在TryActive的函数内,需要检测这个skill和owner active skillList之间的关系。
4.我们使用entity+component的方式,而不是面向对象的方式实现。那么我们定义system和component:
class SkillList: Component {List<ISkill> }
同时, SkillSystem去Update这个SkillListComponent
class SkillControllerSystem