Lyra技术分析:输入方式与GAS技能触发

前言

本文研究一下Lyra技能系统的输入方式触发方式

传统的GAS技能触发方式

GAS中每个技能(GA)通过UAbilitySystemComponent::GiveAbility(const FGameplayAbilitySpec& Spec)添加

在这个spec里面有一个int32 InputID;成员变量, 这个是用来快捷触发技能用的

然后看技能组件内的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

void UAbilitySystemComponent::BindAbilityActivationToInputComponent(UInputComponent* InputComponent, FGameplayAbilityInputBinds BindInfo)
{
UEnum* EnumBinds = BindInfo.GetBindEnum();

SetBlockAbilityBindingsArray(BindInfo);

for(int32 idx=0; idx < EnumBinds->NumEnums(); ++idx)
{
const FString FullStr = EnumBinds->GetNameStringByIndex(idx);

// Pressed event
{
FInputActionBinding AB(FName(*FullStr), IE_Pressed);
AB.ActionDelegate.GetDelegateForManualSet().BindUObject(this, &UAbilitySystemComponent::AbilityLocalInputPressed, idx);
InputComponent->AddActionBinding(AB);
}

// Released event
{
FInputActionBinding AB(FName(*FullStr), IE_Released);
AB.ActionDelegate.GetDelegateForManualSet().BindUObject(this, &UAbilitySystemComponent::AbilityLocalInputReleased, idx);
InputComponent->AddActionBinding(AB);
}
}

将一个枚举转换为int绑定到每个技能触发按键事件上

image-20231116152815806

在收到回调事件后会进行判定并触发对应的inputID的技能

在UE4中, 可以直接将InputAction名称与这个枚举对应起来, 可以达到直接触发

EnhancedInput与GAS技能触发

UE5以后, 传统的InputAction已经被废弃, 这套绑定系统需要调整一下才能触发

实际上我们只需要将EnhancedInput的InputAction与一个枚举对应起来即可

比如建立一个TMap关系

TMap<EAbilityInputKey, UInputAction*>

然后重载BindAbilityActivationToInputComponent事件, 如下

image-20231116153314078

记得, 这个事件是需要手动去触发的, 比如在角色中触发

image-20231116153352887

当然需要将技能与这个枚举建立起对应关系, 或者是在CDO中赋予成员变量, 或者再建立一个索引关系, 在注册技能的时候添加进去即可

那么这样以后, 配置好映射, 就可以正常触发对应的技能了

image-20231116153514678

Lyra的技能触发方式

Lyra的技能触发是围绕Tag的, 即每个技能触发对应一个tag, 这样比枚举更加灵活

Lyra的角色配置使用的是一个叫PawnData的DataAsset

里面保存了ULyraInputConfig用于配置输入

然后这个配置内保存了两组输入配置, 一组用于触发传统的比如移动的输入配置, 另一组用于技能, 我们重点就看技能

TArray<FLyraInputAction> AbilityInputActions;

image-20231116153953690

Lyra使用了自定义的InputCompnent, 添加了几个扩展的模板函数, 比如

image-20231116154102472

因为源生的BindAction模板函数支持动态参数, Lyra就用此扩展了一个支持tag的输入绑定函数

在设置PawnData的时候就把输入配置注册好

image-20231116154213522

在回调函数里直接调用自定义的ASC的对应事件

image-20231116154246898

在ASC中, 输入事件过去的时候会将对应的技能句柄保存到一个数组中

image-20231116154333779

然后在Controller驱动的ULyraAbilitySystemComponent::ProcessAbilityInput函数中做统一处理

image-20231116154721926

Lyra的GA类有一个成员变量用于定义这个技能的触发方式

1
2
3
4
5
6
7
8
9
10
11
12
UENUM(BlueprintType)
enum class ELyraAbilityActivationPolicy : uint8
{
// Try to activate the ability when the input is triggered.
OnInputTriggered,

// Continually try to activate the ability while the input is active.
WhileInputActive,

// Try to activate the ability when an avatar is assigned.
OnSpawn
};

字面意思即可理解, 举个例子, reload技能是OnInputTriggered在按下的时候只触发一次, 开火技能是按下以后一直触发直到松开按键, 被动技能可以设置为OnSpawn在ASC初始化之后就可以触发