战斗核心接口

前言

制作战斗系统是一个复杂的任务,而制作一个干净的,不耦合其他无关系统(如运动系统和库存系统)则更具备挑战。

为了让GCS更纯粹,且不与其他系统产生耦合,GCS提供了GCS_CombatInterface接口。战斗系统中的任何可能需要不同的实现逻辑,或者应该由第三方完成的功能,都通过该接口实现。并通过一个静态函数"GetCombatInterface"调用,这个静态函数会在给定的Actor或其组件上查询Combat接口。

因此你可以参考默认实现,通过蓝图/C++自由地在Actor或者组件中重新实现该接口,或者直接将默认实现复制或继承一份并开始你的自定义。

而在实际代码实现中,那些需要与外部系统交互的代码,我们称其为胶水代码,用于将不同系统联系在一起。

设计图

战斗核心接口.001

默认实现说明

由于GCS已经提供默认实现,所以本文的内容更适合那些喜欢组装不同的系统,或者已经有开发中的项目且希望中途更换战斗解决方案的用户。或者对简单的默认实现不满意的用户。

在GCS的Demo项目中提供了简单的默认实现用于处理如运动状态逻辑,装备切换逻辑等。

在实际的项目中,你大概已经有了自己的库存系统或者运动系统,所以修改CombatInterface的默认实现是集成到你项目中的最佳方式。

同时我自己也拥有通用运动系统和通用库存系统,我也是采用同样的方式替换成了我自己的实现,也完全不影响战斗系统本身的逻辑。

购买了通用运动系统的用户,可以与战斗系统很好地搭配~V~

实现战斗接口

战斗核心接口.002

该接口的每一个函数都有详细的注释以及实现指南,在这里不再重复描述。你可以通过Actor实现该接口,但我建议通过组件的方式实现。

使用战斗接口

通常,你不应该直接使用实现了接口的对象,而是通过GetCombatInterface或者FindCombatInterface来调用相关的接口函数。

以下图为例,你只需要确保AvatarActor或其中的某个组件确实实现了GCS_CombatInterface,那么你就可以正确地获取到战斗接口的引用,并调用相关的函数。

战斗核心接口.003

使用案例

我有一个GA_GCS_Sprint技能,用于控制角色是否奔跑。该技能包含OnSprintStart和OnSprintEnd事件。

由于该技能会影响到角色的运动方式,我并非直接在该技能中设置CharacterMovementComponent的参数,而是通过如下方式进行调用:

战斗核心接口.004
战斗核心接口.005

SetRotationMode举例,在默认实现(BC_GCS_DemoCombatCore)中,

战斗核心接口.006
战斗核心接口.007
战斗核心接口.008

你可以看到,在最后一张截图中,我才真正拿到了CharacterMovementComponent,并设置了相关参数。你可能觉得这样的做法绕了一个大圈,但实际上它有如下好处:

  1. 你确保了GA_GCS_Sprint的可复用性,且不与CharacterMovementComponent耦合。
  2. 你可能会添加新的旋转模式,所以使用Tag足够灵活。
  3. Epic正在开发Mover2.0以替代传统的CharacterMovementComponent,因此当你真的希望切换到Movier2.0的时候,你不需要到处去查找哪里使用到了CharacterMovementComponent