UE 5 스터디/Gameplay Ability System(GAS)

26-13. 아케인 파편 스펠 - (13) 클릭하여 어빌리티 발동, 다른 키를 눌러 어빌리티 취소

Crat3 2025. 3. 27. 15:24

0. 개요

범위 지정 데칼이 켜져있는 상태에서 어빌리티 입력 버튼 뿐 아니라, 마우스 왼쪽 클릭으로 어빌리티를 발동할 수 있게 한다.

범위 지정 데칼이 켜져있는 상태에서 어빌리티 입력 버튼과 마우스 왼쪽 클릭 버튼이 아닌 입력으로 어빌리티를 취소할 수 있게 한다.

 

 

1. 클릭하여 어빌리티 발동

(1) AuraGameplayTags에서 Native 게임플레이 태그 생성

Player.Abilities.WaitForExecute 태그를 생성한다.

	GameplayTags.Player_Abilities_WaitForExecute = UGameplayTagsManager::Get().AddNativeGameplayTag(
		FName("Player.Abilities.WaitForExecute"),
		FString("Player_Abilities_WaitForExecute")
	);

 

 

(2) ASC의 AbilityInputTagPressed 함수 수정

어빌리티를 발동하기 위해 어빌리티의 입력 태그에 해당되는 키가 눌리면 발동하는 함수이다.

아래의 슈도 코드를 따라서 코드를 작성한다.

        /*
        1. Player.Abilities.WaitForExecute 태그가 부여된 ASC에 대해
        2. Player.Abilities.WaitForExecute 태그를 가진 어빌리티의
        3. 입력태그를 체크
        - 어빌리티의 입력태그가 LMB인 경우?
        - 어빌리티의 입력태그가 LMB가 아닌 경우?
        - 다른 키를 누르면 입력을 취소?
        */
void UAuraAbilitySystemComponent::AbilityInputTagPressed(const FGameplayTag& InputTag)
{
    if (InputTag.IsValid() == false)
        return;

    FAuraGameplayTags GameplayTags = FAuraGameplayTags::Get();

    FScopedAbilityListLock ActiveScopeLoc(*this);
    for (FGameplayAbilitySpec& AbilitySpec : GetActivatableAbilities())
    {
        /*
        1. Player.Abilities.WaitForExecute 태그가 부여된 ASC에 대해
        2. Player.Abilities.WaitForExecute 태그를 가진 어빌리티의
        3. 입력태그를 체크
        - 어빌리티의 입력태그가 LMB인 경우?
        - 어빌리티의 입력태그가 LMB가 아닌 경우?
        - 다른 키를 누르면 입력을 취소?
        */
        if (HasMatchingGameplayTag(GameplayTags.Player_Abilities_WaitForExecute))
        {
            if (AbilitySpec.IsActive())
            {
                // 왼쪽 버튼 클릭 혹은 어빌리티 버튼 입력
                if (InputTag.MatchesTagExact(GameplayTags.InputTag_LMB)
                    || AbilitySpec.DynamicAbilityTags.HasTag(InputTag))
                {
                    // 해당 어빌리티에 대해 누르기 발동
                    AbilitySpecInputPressed(AbilitySpec);
                    InvokeReplicatedEvent(EAbilityGenericReplicatedEvent::InputPressed, AbilitySpec.Handle, AbilitySpec.ActivationInfo.GetActivationPredictionKey());
                    return;
                }
                else
                {
                    // 다른 키 입력 시 어빌리티 취소
                    CancelAbilityHandle(AbilitySpec.Handle);
                }
            }
        }
        // 어빌리티에 할당된 입력태그가 입력으로 받은 입력태그와 일치
        else if (AbilitySpec.DynamicAbilityTags.HasTagExact(InputTag))
        {
            // 해당 어빌리티에 대해 누르기 발동
            AbilitySpecInputPressed(AbilitySpec);
            if (AbilitySpec.IsActive() == false)
            {
                InvokeReplicatedEvent(EAbilityGenericReplicatedEvent::InputPressed, AbilitySpec.Handle, AbilitySpec.ActivationInfo.GetActivationPredictionKey());
                return;
            }
        }
    }
}

 

- 로직 순서

1. ASC가 Player.Abilities.WaitForExecute 태그를 가지고 있는지 확인한다.

-> 해당 태그가 있다면 입력 버튼이 왼쪽 버튼이거나, 어빌리티의 입력 태그에 해당하는 버튼인지 확인한다.

-> 맞으면 어빌리티를 실행한다.

↪ 아니면 어빌리티를 취소한다.

 

2. ASC가 해당 태그가 없다면 일반적인 동작으로 어빌리티를 실행한다.

 

 

(3) GA_ArcaneShards에서 ASC에 태그 부여하기

- 처음에 범위 지정 데칼이 켜졌을 때 ASC에 Loose Gameplay Tags를 추가한다.

- Player.Abilities.WaitForExecute를 멤버 변수로 만든다(타입은 게임플레이 태그 배열).

- 이 함수는 게임플레이 태그 컨테이너를 매개 변수로 받기 때문에, 분해하여 배열을 받도록 하고, 멤버 변수를 전달한다.

 

 

(4) 어빌리티 종료 후 ASC에서 태그 제거하기

- WasCancelled 불리언은 어빌리티가 다른 행동에 의해 취소되었을 때 true를 반환한다.

해당 불리언을 사용하여 취소되었다면 범위 지정 데칼을 숨긴다.

- 이후에 ASC로부터 부여했던 태그를 제거한다.