게임 개발 메모장
[ UE5 ] Input(입력) 을 Gameplay Ability System을 활용 본문
AuraInputConfig.h
// Copyright Druid Mechanics
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "GameplayTagContainer.h"
#include "AuraInputConfig.generated.h"
USTRUCT(BlueprintType)
struct FAuraInputAction
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly)
const class UInputAction* InputAction = nullptr;
UPROPERTY(EditDefaultsOnly)
FGameplayTag InputTag = FGameplayTag();
};
/**
*
*/
UCLASS()
class AURA_API UAuraInputConfig : public UDataAsset
{
GENERATED_BODY()
public:
const UInputAction* FindAbilityInputActionForTag(const FGameplayTag& InputTag, bool bLogNotFound = false) const;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
TArray<FAuraInputAction> AbilityInputActions;
};
AuraInputConfig.cpp
// Copyright Druid Mechanics
#include "Input/AuraInputConfig.h"
const UInputAction* UAuraInputConfig::FindAbilityInputActionForTag(const FGameplayTag& InputTag, bool bLogNotFound) const
{
for (const FAuraInputAction& Action: AbilityInputActions)
{
if (Action.InputAction && Action.InputTag == InputTag)
{
return Action.InputAction;
}
}
if (bLogNotFound)
{
UE_LOG(LogTemp, Error, TEXT("Can't find AbilityInputAction for InputTag [%s], on InputConfig [%s]"), *InputTag.ToString(), *GetNameSafe(this));
}
return nullptr;
}
AuraGameplayTags.cpp
void FAuraGameplayTags::InitializeNativeGameplayTags()
{
//,,,,
/*
* Input Tags
*/
GameplayTags.InputTag_LMB = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("InputTag.LMB"),
FString("Input Tag for Left Mouse Button")
);
GameplayTags.InputTag_RMB = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("InputTag.RMB"),
FString("Input Tag for Right Mouse Button")
);
GameplayTags.InputTag_1 = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("InputTag.1"),
FString("Input Tag for 1 key")
);
GameplayTags.InputTag_2 = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("InputTag.2"),
FString("Input Tag for 2 key")
);
GameplayTags.InputTag_3 = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("InputTag.3"),
FString("Input Tag for 3 key")
);
GameplayTags.InputTag_4 = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("InputTag.4"),
FString("Input Tag for 4 key")
);
//,,,,
}
AuraPlayerController.cpp
SetupInputComponent() : 바인딩 작업
AuraInputComponent -> BindAbilityActions
(InputConfig, this, &ThisClass::AbilityInputTagPressed, &ThisClass::AbilityInputTagReleased, &ThisClass::AbilityInputTagHeld);
void AAuraPlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
UAuraInputComponent* AuraInputComponent = CastChecked<UAuraInputComponent>(InputComponent);
AuraInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AAuraPlayerController::Move);
AuraInputComponent->BindAction(ShiftAction, ETriggerEvent::Started, this, &AAuraPlayerController::ShiftPressed);
AuraInputComponent->BindAction(ShiftAction, ETriggerEvent::Completed, this, &AAuraPlayerController::ShiftReleased);
AuraInputComponent->BindAbilityActions(InputConfig, this, &ThisClass::AbilityInputTagPressed, &ThisClass::AbilityInputTagReleased, &ThisClass::AbilityInputTagHeld);
}
void AAuraPlayerController::AbilityInputTagPressed(FGameplayTag InputTag)
{
if (GetASC() && GetASC()->HasMatchingGameplayTag(FAuraGameplayTags::Get().Player_Block_InputPressed))
{
return;
}
if (InputTag.MatchesTagExact(FAuraGameplayTags::Get().InputTag_LMB))
{
if (IsValid(ThisActor))
{
TargetingStatus = ThisActor->Implements<UEnemyInterface>() ? ETargetingStatus::TargetingEnemy : ETargetingStatus::TargetingNonEnemy;
}
else
{
TargetingStatus = ETargetingStatus::NotTargeting;
}
bAutoRunning = false;
}
if (GetASC()) GetASC()->AbilityInputTagPressed(InputTag);
}
void AAuraPlayerController::AbilityInputTagReleased(FGameplayTag InputTag)
{
if (GetASC() && GetASC()->HasMatchingGameplayTag(FAuraGameplayTags::Get().Player_Block_InputReleased))
{
return;
}
if (!InputTag.MatchesTagExact(FAuraGameplayTags::Get().InputTag_LMB))
{
if (GetASC()) GetASC()->AbilityInputTagReleased(InputTag);
return;
}
if (GetASC()) GetASC()->AbilityInputTagReleased(InputTag);
if (TargetingStatus != ETargetingStatus::TargetingEnemy && !bShiftKeyDown)
{
const APawn* ControlledPawn = GetPawn();
if (FollowTime <= ShortPressThreshold && ControlledPawn)
{
if (IsValid(ThisActor) && ThisActor->Implements<UHighlightInterface>())
{
IHighlightInterface::Execute_SetMoveToLocation(ThisActor, CachedDestination);
}
else if (GetASC() && !GetASC()->HasMatchingGameplayTag(FAuraGameplayTags::Get().Player_Block_InputPressed))
{
UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, ClickNiagaraSystem, CachedDestination);
}
if (UNavigationPath* NavPath = UNavigationSystemV1::FindPathToLocationSynchronously(this, ControlledPawn->GetActorLocation(), CachedDestination))
{
Spline->ClearSplinePoints();
for (const FVector& PointLoc : NavPath->PathPoints)
{
Spline->AddSplinePoint(PointLoc, ESplineCoordinateSpace::World);
}
if (NavPath->PathPoints.Num() > 0)
{
CachedDestination = NavPath->PathPoints[NavPath->PathPoints.Num() - 1];
bAutoRunning = true;
}
}
}
FollowTime = 0.f;
TargetingStatus = ETargetingStatus::NotTargeting;
}
}
void AAuraPlayerController::AbilityInputTagHeld(FGameplayTag InputTag)
{
if (GetASC() && GetASC()->HasMatchingGameplayTag(FAuraGameplayTags::Get().Player_Block_InputHeld))
{
return;
}
if (!InputTag.MatchesTagExact(FAuraGameplayTags::Get().InputTag_LMB))
{
if (GetASC()) GetASC()->AbilityInputTagHeld(InputTag);
return;
}
if (TargetingStatus == ETargetingStatus::TargetingEnemy || bShiftKeyDown)
{
if (GetASC()) GetASC()->AbilityInputTagHeld(InputTag);
}
else
{
FollowTime += GetWorld()->GetDeltaSeconds();
if (CursorHit.bBlockingHit) CachedDestination = CursorHit.ImpactPoint;
if (APawn* ControlledPawn = GetPawn())
{
const FVector WorldDirection = (CachedDestination - ControlledPawn->GetActorLocation()).GetSafeNormal();
ControlledPawn->AddMovementInput(WorldDirection);
}
}
}
UAuraAbilitySystemComponent::AbilityInputTagHeld() 실행
void UAuraAbilitySystemComponent::AbilityInputTagHeld(const FGameplayTag& InputTag)
{
if (!InputTag.IsValid()) return;
FScopedAbilityListLock ActiveScopeLoc(*this);
for (FGameplayAbilitySpec& AbilitySpec : GetActivatableAbilities())
{
if (AbilitySpec.DynamicAbilityTags.HasTagExact(InputTag))
{
AbilitySpecInputPressed(AbilitySpec);
if (!AbilitySpec.IsActive())
{
TryActivateAbility(AbilitySpec.Handle);
}
}
}
}
'언리얼 엔진 > 기능' 카테고리의 다른 글
[UE5] Check-In/Out (0) | 2024.03.16 |
---|---|
[ UE5 ] GameplayAbilitySystem : 심화 (0) | 2024.01.10 |
[ UE5 ] GameplayAbilitySystem : GameplayCue (0) | 2024.01.10 |
[ UE5 ] GameplayAbilitySystem : AbilityTask (0) | 2024.01.10 |
[ UE5 ] GameplayAbilitySystem : Gameplay Ability (0) | 2024.01.10 |