0124技能系统

战斗行动机制

战斗行动

是什么

我们将造成伤害、给与治疗、赋给效果、缩放技能等由战斗实体发起的操作称为战斗行动CombatAction,战斗行动独立于战斗实体,存储着此次战斗行动需要用到的所有数据,并持有相关战斗实体的引用

为什么

复杂的战斗会在战斗的过程中插入各种效果和计算,如果只是简单的用一套方法,会难以区分某个效果应该写在攻击者的流程还是写在受击者的流程里,抽象出战斗行动这个概念后,我们就可以把难以区分的效果放进战斗行动里

行动点

是什么

定义:一次战斗行动会经过并触发相关战斗实体一系列行动点

例子:比如一次造成伤害的战斗行动,会触发攻击者造成伤害行动点和受击者承受伤害行动点。一次给与治疗的战斗行动,会触发施法者给予治疗行动点和被施法者接受治疗行动点

世界法则

是什么

定义:世界法则是决定战斗行动(伤害行动或技能行动等)触发后产生的结果

例子:就比如你赤手重拳出击,你这一击是对敌人造成伤害还是对自己造成伤害取决于你攻击的对象,你自己是没有办法决定的。如果你攻击的是一个鸡蛋,那么鸡蛋会被打碎而你毫发无伤,但如果你攻击的是一个铁球,那么结果会变成铁球毫发无伤而你痛得甩手。这就是现实世界的法则。

联系

战斗实体发起战斗行动,战斗行动触发行动点,世界法则决定行动的结果

image-20210123202724960

能力系统

我们把可以通过应用效果、修改数据来影响角色的属性或状态的这类功能称为能力,这类功能有技能、被动、buff、debuff

image-20210123202822142

能力实体AbilityEntity

是什么

能力实体可以存储某个能力的配置数据(伤害、消耗等)和状态数据(冷却计时、击杀计数等),配置数据是策划配置的固定数据,状态数据时在战斗中会变化的数据

能力执行体AbilityExecution

是什么

能力执行体是用来执行能力表现、触发能力效果应用的地方。可以存储一些表现执行相关的临时的状态数据

技能执行体

通常buff和被动不会有很明显的表现行为,一般来说具有复杂能力表现行为的是主动技能,主动技能的释放一般会伴随玩家的输入,包含下面三种类型:

  • 目标战斗实体
  • 位置
  • 方向

能力任务AbilityTask

在能力执行体中我们可以创建一系列的能力任务来实现各种复杂的技能表现,比如播放动作、创建特效、创建触发器

Status状态效果

状态Status

是什么

状态效果会影响角色的行为和战斗的结果,最终确定角色当前时刻的状态。我们将增益效果称为buff,减益效果称为debuff

状态效果类型
  • 属性修饰

诸如提升10%的攻击力、增加30点护甲值这些状态效果我们称之为属性修饰

  • 行为禁制

行为禁止与控制,像眩晕、沉默、恐惧等就属于行为禁制类型的状态效果。比如眩晕包含移动禁止、攻击禁止、施法禁止,沉默包含施法禁止,恐惧包含施法禁止、攻击禁止、移动控制。

  • 逻辑触发

buff的逻辑触发机制分为3种,时间触发、条件触发、行为触发。比如按时间触发有几秒后触发伤害、每间隔多少秒造成伤害等,按行为动作触发有受伤时怎么怎么样、攻击时怎么怎么样等,按条件触发有当生命值低于多少时怎么样、当受到的伤害大于多少时怎么样等。(条件机制比较复杂些,基本每种类型的条件都需要单独写代码判断,这个最好是通过抽象分离和事件解耦来减少代码的侵入性。)

  • 其他

以上3种虽然囊括了大部分的buff效果,但依然还是会有一些非常特殊的效果可能需要单独写逻辑代码

image-20210123162004878

Buff和被动

buff和被动本质是一种东西,唯一区别就是被动开始装载就一直存在,而buff的装载时机任意,而且可以一直存在或者短暂存在

StatusAbility

状态想过也叫状态能力,属于能力的一种类型,继承于AbilityEntity

StatusAbilityExecution

状态能力执行体,这个用来实现一些表现效果,比如装载了一个被动,每隔几秒就会释放一个逐渐向扩散的光环对敌人造成伤害或者是对己方治疗,就可以用状态能力执行体实现

ConditionEntity

在一些比较复杂的状态效果里,按条件触发的效果会比较多,我们会抽象出一个条件实体ConditionEntity,并统一由条件管理组件ConditionManageComponent管理,每个战斗实体都会持有一个

Skill技能

Skill和Status的区别

技能:玩家主动释放,释放之后有一次性的短暂的特效、动作和表现效果,这种能力我们可以将其称为技能

状态:被动接受,或者是由技能造成的持续一段时间的状态效果,将其称为状态

image-20210123162440317

SkillAbility

我们将抽象的技能概念表示为SkillAbility,实际的技能表现为SkillExecution技能执行体。SkillAbility代表这个技能的状态和信息,比如等级、冷却、是否可用、技能类型等,它是一直挂载在战斗实体上的

SkillExecution

SkillExecution技能执行体由SkillAbility创建,临时挂载到战斗实体上,一次性的由短暂的生命周期的东西,它主要负责技能释放后表现出来的短暂的一系列的特效和效果,。可用结合皆能编辑器或行为树编辑器来实现技能表现

image-20210123164013401

代码分析

黑火球术

Hero加载技能配置绑定按键

        SkillConfigObject config = Resources.Load<SkillConfigObject>("SkillConfigs/Skill_1001_黑火球术");
        SkillAbility abilityA = CombatEntity.AttachSkill<Skill1001Entity>(config);
        CombatEntity.BindSkillInput(abilityA, KeyCode.Q);

SkillPreviewComponent当我们按下Q的时候,会出现圆形指示器,碰到怪物会变成红色

    public void EnterPreview()
    {
        CancelPreview();
        Previewing = true;
        if (PreviewingSkill is Skill1001Entity)
        {
            TargetSelectManager.Instance.Show(OnSelectedTarget);
        }
    }

image-20210124201936282

SkillPreviewComponent,选中怪物单击左键,会触发上面的回调函数,并生成技能行动,然后执行技能

    private void OnInputTarget(CombatEntity combatEntity)
    {
        if (PreviewingSkill.Spelling)
        {
            return;
        }
        //Log.Debug($"OnInputTarget {combatEntity}");
        var action = GetEntity<CombatEntity>().CreateCombatAction<SpellSkillAction>();
        action.SkillAbility = PreviewingSkill;
        action.SkillAbilityExecution = PreviewingSkill.CreateAbilityExecution() as SkillAbilityExecution;
        action.SkillAbilityExecution.InputCombatEntity = combatEntity;
        action.SpellSkill();
    }

    private void OnInputPoint(Vector3 point)
    {
        if (PreviewingSkill.Spelling)
        {
            return;
        }
        //Log.Debug($"OnInputPoint {point}");
        var action = GetEntity<CombatEntity>().CreateCombatAction<SpellSkillAction>();
        action.SkillAbility = PreviewingSkill;
        //创建能力执行体
        action.SkillAbilityExecution = PreviewingSkill.CreateAbilityExecution() as SkillAbilityExecution;
        action.SkillAbilityExecution.InputPoint = point;
        //执行技能
        action.SpellSkill();
    }

Skill1001Entity,上面的逻辑会调用子类Skill1001的方法,并执行该技能,执行技能的时候会创建一个能力任务CastProjectileTask,该任务会根据配置信息生成”黑火球“,并按照目标点移动

image-20210124202011125

public class Skill1001Entity : SkillAbility
{
    public override AbilityExecution CreateAbilityExecution()
    {
        var abilityExecution = Entity.CreateWithParent<Skill1001Execution>(this.GetParent<CombatEntity>(), this);
        return abilityExecution;
    }
}

public class Skill1001Execution : SkillAbilityExecution
{
    public override async void BeginExecute()
    {
        base.BeginExecute();

        var taskData = new CastProjectileTaskData();
        taskData.ProjectilePrefab = (AbilityEntity as Skill1001Entity).SkillConfigObject.SkillEffectObject;
        //创建能力任务
        var task = Entity.CreateWithParent<CastProjectileTask>(this, taskData);
        //执行能力任务
        await task.ExecuteTaskAsync();

        //应用能力效果
        AbilityEntity.ApplyAbilityEffectsTo(InputCombatEntity);

        EndExecute();
    }
}

“黑火球”移动到目标点,会根据技能配置信息,应用能力效果

        public virtual void ApplyAbilityEffectsTo(CombatEntity targetEntity)
        {
            List<Effect> Effects = null;
            if (ConfigObject is SkillConfigObject skillConfigObject)
            {
                Effects = skillConfigObject.Effects;
            }
            if (ConfigObject is StatusConfigObject statusConfigObject)
            {
                if (statusConfigObject.EnabledLogicTrigger)
                {
                    Effects = statusConfigObject.Effects;
                }
            }
            if (Effects == null)
            {
                return;
            }
            foreach (var effectItem in Effects)
            {
                ApplyEffectTo(targetEntity, effectItem);
            }
        }

image-20210124200513866

DamageAction,接着会触发伤害行动,根据配置信息还有数值公式,目标怪物会扣血

// TODO

AssignEffectAction,最后还有触发赋予效果行动,目标怪物会中毒

//TODO

技能释放流程如下:

  • 生成技能行动
  • 执行技能
  • 创建能力任务
  • 应用能力效果
  • 触发伤害行动
  • 触发赋予效果行动

参考资料

https://zhuanlan.zhihu.com/p/272216809

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值