Gameplay Ability System의 입력 바인딩 방법 연구

Woogle·2024년 8월 25일
0

언리얼 엔진 5

목록 보기
59/63

📄 개요

Gameplay Ability System(GAS)은 강력한 게임 개발 프레임워크다.
Data-Driven 방식으로 각 객체간의 종속성을 최소화할 수 있고, 멀티플레이 게임을 만들 수도 있다.

하지만 단점도 있다.
그 중 하나가 유저 입력과 어빌리티를 연결하는 바인딩 방식이다. 방식이 표준화되지 않아 개발자마다 다양하게 구현한다.
여러가지 입력 바인딩 방식과 장단점을 조사했다.


1. Input ID를 사용하는 방법

  • Gameplay Ability 클래스를 상속받은 클래스를 만들고 InputID를 어빌리티마다 부여한다.
  • 에픽게임즈의 파라곤에서 사용한 방식.
UENUM(BlueprintType)
enum class EAbilityInputID : uint8
{
    None         UMETA(DisplayName = "None"),
    Confirm      UMETA(DisplayName = "Confirm"),
    Cancel       UMETA(DisplayName = "Cancel"),
    Fire         UMETA(DisplayName = "FireAbility"),
    Jump         UMETA(DisplayName = "JumpAbility")
};

void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

    if (AbilitySystemComponent)
    {
        AbilitySystemComponent->BindAbilityActivationToInputComponent(PlayerInputComponent,
            FGameplayAbilityInputBinds(
                "Confirm", "Cancel", "EAbilityInputID", 
                static_cast<int32>(EAbilityInputID::Confirm), 
                static_cast<int32>(EAbilityInputID::Cancel)
            ));

        PlayerInputComponent->BindAction("FireAbility", IE_Pressed, this, &AMyCharacter::FireAbility);
    }
}
  • 👍장점: 구버전 Input(Action/Axis Mappings)과도 잘 호환된다.
  • 👎단점: C++ 코드에서 바인딩하므로 유연함이 떨어진다.

2. Dynamic Ability Tags 로 맵핑하는 방법

  • AbilitySpec.DynamicAbilityTags에 입력 태그를 넣어서 사용하는 방식
  • 라이라 샘플 프로젝트에서는 LyraAbilitySet이라는 데이터에셋이 위의 바인딩 작업을 진행한다.
void UMyAbilitySystemComponent::GrantInputAbility(FGameplayTag InputTag, const TSubclassOf<UGameplayAbility>& Ability)
{
	FGameplayAbilitySpec AbilitySpec(Ability);
	AbilitySpec.SourceObject = GetAvatarActor();
	AbilitySpec.DynamicAbilityTags.AddTag(InputTag);
	GiveAbility(AbilitySpec);
}

void UMyAbilitySystemComponent::OnAbilityInputPressed(const FGameplayTag& InputTag)
{
	for (const FGameplayAbilitySpec& AbilitySpec : GetActivatableAbilities())
	{
		if (AbilitySpec.DynamicAbilityTags.HasTagExact(InputTag))
		{
			TryActivateAbility(AbilitySpec.Handle);
		}
	}
}
  • 👍장점: 유연성이 높다. 라이라처럼 데이터에셋 안에 Ability와 Input Tag를 모아두면 보기 깔끔해진다.
  • 👎단점: 어빌리티와 입력을 각자 따로 맵핑해야하므로 복잡도가 있다.

3. Input Action에서 어빌리티 실행

  • BP에서 Input Action이 실행될 때 TryActivateAbilitiesByTag()를 실행한다.
  • 어빌리티에 AbilityTags를 설정해야한다.
  • 👍장점: 프로그래머 지원 없이도 로직을 구현할 수 있다.
  • 👎단점: 런타임 중에 AbilityTags 변경이 불가능하다.

📄 결론

  • Gameplay Ability 자체만으로는 직접 입력을 받지 못하기 때문에 입력 바인딩을 직접 구현해야하고, 그 구현 방법마다 장단점이 있다.
  • 개인적으로는 마지막 방법이 에픽게임즈가 추구하는 방향과 제일 부합한다고 생각한다. 디자이너가 직접 게임플레이 로직을 구현할 수 있기 때문이다.

📄 참고자료

profile
노력하는 게임 개발자

0개의 댓글