vault backup: 2024-01-29 15:04:48
This commit is contained in:
parent
598d61b281
commit
9691c61e10
111
03-UnrealEngine/Gameplay/GAS/GAS Ability输入绑定.md
Normal file
111
03-UnrealEngine/Gameplay/GAS/GAS Ability输入绑定.md
Normal file
@ -0,0 +1,111 @@
|
||||
---
|
||||
title: Untitled
|
||||
date: 2024-01-29 13:23:24
|
||||
excerpt:
|
||||
tags:
|
||||
rating: ⭐
|
||||
---
|
||||
# 前言
|
||||
相关函数主要为:
|
||||
- AbilitySystemComponent->BindToInputComponent():只绑定名称为AbilityConfirm与AbilityCancel的InputAction。
|
||||
- AbilitySystemComponent->BindAbilityActivationToInputComponent():输入InputComponent、FGameplayAbilityInputBinds、FTopLevelAssetPath(枚举类路径)、枚举ID,之后绑定GA与Input。
|
||||
- AbilitySystemComponent->SetBlockAbilityBindingsArray():设置Block列表。
|
||||
|
||||
# GAS
|
||||
BindAbilityActivationToInputComponent()的绑定方式如果ASC在Character中,可以在SetupPlayerInputComponent()中进行绑定:
|
||||
```c
|
||||
// Bind to AbilitySystemComponent
|
||||
FTopLevelAssetPath AbilityEnumAssetPath = FTopLevelAssetPath(FName("/Script/GASDocumentation"), FName("EGDAbilityInputID"));
|
||||
AbilitySystemComponent->BindAbilityActivationToInputComponent(PlayerInputComponent, FGameplayAbilityInputBinds(FString("ConfirmTarget"),
|
||||
FString("CancelTarget"), AbilityEnumAssetPath, static_cast<int32>(EGDAbilityInputID::Confirm), static_cast<int32>(EGDAbilityInputID::Cancel)));
|
||||
```
|
||||
|
||||
其内部主要是类似这样的方式进行绑定:
|
||||
```c++
|
||||
// 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);
|
||||
}
|
||||
```
|
||||
|
||||
AbilityLocalInputPressed()与AbilityLocalInputReleased()会执行:
|
||||
1. 触发多播委托
|
||||
2. TryActivateAbility() 或者 AbilitySpecInputPressed()。
|
||||
|
||||
感觉可以自己实现一个BindAbilityActivationToInputComponent()的绑定逻辑,ASC自带的逻辑有点2。
|
||||
GAS使用的是**InputComponent->AddActionBinding**,而增强输入使用**PlayerEnhancedInputComponent->BindAction**。本质是一样的。
|
||||
```c++
|
||||
FInputActionBinding& BindAction( const FName ActionName, const EInputEvent KeyEvent, UserClass* Object, typename FInputActionHandlerSignature::TMethodPtr< UserClass > Func )
|
||||
{
|
||||
FInputActionBinding AB( ActionName, KeyEvent );
|
||||
AB.ActionDelegate.BindDelegate(Object, Func);
|
||||
return AddActionBinding(MoveTemp(AB));
|
||||
}
|
||||
```
|
||||
|
||||
## 绑定输入而不激活能力
|
||||
如果您不希望`GameplayAbilities`在按下输入时自动激活,但仍将它们绑定到输入以与 一起使用`AbilityTasks`,则可以向您的`UGameplayAbility`子类添加一个新的 bool 变量`bActivateOnInput`,该变量默认为`true`并覆盖`UAbilitySystemComponent::AbilityLocalInputPressed()`。
|
||||
```c
|
||||
void UGSAbilitySystemComponent::AbilityLocalInputPressed(int32 InputID)
|
||||
{
|
||||
// Consume the input if this InputID is overloaded with GenericConfirm/Cancel and the GenericConfim/Cancel callback is bound
|
||||
if (IsGenericConfirmInputBound(InputID))
|
||||
{
|
||||
LocalInputConfirm();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsGenericCancelInputBound(InputID))
|
||||
{
|
||||
LocalInputCancel();
|
||||
return;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
ABILITYLIST_SCOPE_LOCK();
|
||||
for (FGameplayAbilitySpec& Spec : ActivatableAbilities.Items)
|
||||
{
|
||||
if (Spec.InputID == InputID)
|
||||
{
|
||||
if (Spec.Ability)
|
||||
{
|
||||
Spec.InputPressed = true;
|
||||
if (Spec.IsActive())
|
||||
{
|
||||
if (Spec.Ability->bReplicateInputDirectly && IsOwnerActorAuthoritative() == false)
|
||||
{
|
||||
ServerSetInputPressed(Spec.Handle);
|
||||
}
|
||||
|
||||
AbilitySpecInputPressed(Spec);
|
||||
|
||||
// Invoke the InputPressed event. This is not replicated here. If someone is listening, they may replicate the InputPressed event to the server.
|
||||
InvokeReplicatedEvent(EAbilityGenericReplicatedEvent::InputPressed, Spec.Handle, Spec.ActivationInfo.GetActivationPredictionKey());
|
||||
}
|
||||
else
|
||||
{
|
||||
UGSGameplayAbility* GA = Cast<UGSGameplayAbility>(Spec.Ability);
|
||||
if (GA && GA->bActivateOnInput)
|
||||
{
|
||||
// Ability is not active, so try to activate it
|
||||
TryActivateAbility(Spec.Handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# SDHGame
|
||||
李兄是在状态机每个节点的StateBegin()中调用CreateDynamicSkillInputActionMappingContext()进行动态绑定的。
|
Loading…
x
Reference in New Issue
Block a user