저번 글에서는 빌드에 쓰이는 .cs 파일, 로그 채널, 게임 플레이 태그를 정의해 둔 방식 등에 대해서 알아봤습니다. 파일을 정리해 둔 순서상 외부에 노출되어 있는 파일 위주로 확인을 해 본 것입니다.

이번 글에서는 Lyra Starter Game에서 쓰인 GameplayAbilitySystem에 대해서 알아보고자 합니다. 워낙 방대한 시스템, 플러그인이기도 하고 프로젝트 전반적으로도 여기저기 쓰였을 것이지만 일단 C++ 소스코드에서 Lyra Starter Game 프로젝트 내 AbilitySystem 폴더를 위주로 확인해보겠습니다.

 

솔루션 탐색기

  • Lyra Starter Game 프로젝트에서 소스코드를 모아둔 곳을 보면 A가 알파벳의 시작 문자이기 때문에 AbilitySystem 폴더가 가장 최상단에 올라와 있는 것을 볼 수 있습니다.

 

AbilitySystem

분석 이전에 AbilitySystem에 대해서 간단히 정리하고 가겠습니다.

  • AbilitySystem은 게임 제작에 있어서 보편적인 기능들을 모아둔 플러그인, 모듈 혹은 시스템으로 게임 개발에 걸리는 시간을 비약적으로 줄여줄 수 있습니다.
  • 현재 서비스 중인 포트나이트에서도 이 시스템을 사용하여 문제없이 서비스하고 있으므로 믿고 사용할 수 있습니다.
  • 아래에는 AbilitySystem이 가지는 핵심 구성 요소들을 간략하게 적어보겠습니다.
    • AbilitySystemComponent : 이 컴포넌트를 통해 대부분의 동작이 이루어집니다. 직접적으로 연관있는 클래스는 GameplayAbility, AttributeSet 정도라고 할 수 있습니다.
    • GameplayAbility : 기능의 집합 혹은 액션(몽타주 재생 등)에 대해 하나의 어빌리티로서 다룰 수 있으며, 어빌리티 내에서는 AbilityTask를 통해 조금 더 심층적인 분화가 가능하고 타겟이 있는 경우 TargetActor 클래스를 사용하여 작업하게 됩니다. 어빌리티 발동에 따라 GameplayEffect가 발동하여 Attribute에 변화(Hp, Damage 등)를 주는 것이 보편적인 접근 방법입니다.
      • AbilityTask : Ability내에서도 구분된 작업의 단위입니다.
      • TargetActor : 타겟팅을 해야한다면 이 클래스를 사용하면 됩니다.
    • AttributeSet : Attribute를 모아놓은 집합입니다. Attribute란 Hp, Damage, Level 등 캐릭터가 가지는 Property를 대체하게 됩니다. Attribute는 float 타입인 2가지 value로 구분되는데, 1) Base 2) Current 입니다. 예를 들어 5초 간 체력이 300 늘어났다가 다시 원상복구하는 상황에선 Base 값은 건드리지 않고 Current 값만 바꾸게 됩니다. 이러한 작업은 이미 GameplayEffect에 구현되어 있고 블루프린트에서 몇 가지 조작을 통해서 쉽게 구현도 가능합니다.
    • GameplayEffect : 주로 Attribute의 제어에 쓰이는 클래스입니다. 체력을 깎는 Effect, 공격력을 5초 간 올려주는 Buff를 주는 Effect 등 미리 정의해 둔 Effect Class를 통해 손쉽게 Attribute를 제어할 수 있고, 이 때 Effect를 적용하기 위해 AbilitySystemComponent를 통해 Self(자기자신)에게 적용할지, Target(상대방)에게 적용할지를 코딩할 수 있습니다. Effect라는 단어가 particle이나 특수효과로 혼동할 수 있으나 그런 것은 아니고 Effect는 근본적으로 Attribute 제어를 목적으로 만든 클래스입니다. particle이나 특수효과는 Effect 발동에 따라 GameplayCue 클래스를 통해 손쉽게 제어할 수 있습니다.
    • GameplayCue : 시각적인 장식성 효과나 사운드 효과에 주로 사용되는 클래스이며, 부착된 GameplayTag를 통해 손쉽게 어떤 GameplayCue를 적용할지 구분할 수 있습니다. (클래스 래퍼런스가 아닌 GameplayCue에 해당하는 Tag를 알고 있다면 발동가능하다는 뜻입니다.) 로직에 영향을 끼치지 않고 휘발성의 효과를 일으키는데 주로 쓰이기 때문에 멀티플레이 환경에선 서버에서 MultiCastRPC를 통해 주로 다른 클라이언트로 전파됩니다.

 

자체 상속

  • LyraAbilitySystemComponent, LyraGameplayAbility, LyraAttributeSet은 각각 AbilitySystemComponent, GameplayAbility, AttributeSet을 상속받아 추가적인 기능 구현을 했습니다.
  • 부가적인 기능이 별로 없는 LyraAttributeSet을 제외하고 LyraAbilitySystemComponent, LyraGameplayAbility는 밑에서 좀 더 알아보겠습니다.

 

LyraAbilitySystemComponent

  • 분석에 앞서 크게 3가지 섹션으로 구분지어서 생각하면 될 것 같습니다.
    • 자체 제작한 함수 (non virtual)
    • 오버라이드한 함수 (virtual)
    • 멤버 변수

자체 제작 / 오버라이드 / 변수

  • 자체 제작한 함수
    • CancelAbilitiesByFunc : 모든 어빌리티에 대해 취소용 함수를 돌려서 취소 조건에 맞으면 취소합니다.
    • CancelInputActivatedAbilities : Input을 통해 발동된 Abilitiy들을 취소합니다.
    • AbilityInputTagPressed : Tag(Input 관련)에 해당하는 Ability가 있다면 자체적으로 (핸들을) 관리합니다.
    • AbilityInputTagReleased : Tag(Input 관련)에 해당하는 Ability가 있다면 자체적으로 (핸들을) 관리합니다.
    • ProcessAbilityInput : 위에서 언급한 두 함수를 통해 관리하는 Ability를 실제적으로 발동합니다. (Input에 해당하는 어빌리티는 바로 발동하는 것이 아닌 AbilityInputTagPressed를 거쳐 ProcessAbilityInput을 통해 발동합니다.)
    • ClearAbilityInput : Input을 통해 발동 대기 중인 Ability들을 모두 지웁니다.
    • IsActivationGroupBlocked : 열거형을 통해 발동을 막을지 여부를 반환합니다.
    • AddAbilityToActivationGroup : Ability를 발동 시 어떤 그룹(열거형)에 속할지 정합니다.
    • RemoveAbilityToActivationGroup : 위 함수에서 추가한 내용의 반대를 합니다.
    • CancelActivationGroupAbilities : Group에 해당하는 어빌리티를 모두 지웁니다.
    • AddDynamicTagGameplayEffect : Tag를 부여하는 Effect를 자신에게 적용합니다.
    • RemoveDynamicTagGameplayEffect : Tag를 부여한 Effect를 제거합니다.
    • GetAbilityTargetData : Ability가 갖고 있는 TargetData를 반환합니다.
    • SetTargetRelationshipMapping : Ability Tag가 가지는 관계 정보 데이터(Block, Cancel, Required, Activation)를 얻어옵니다. (데이터 에셋)
    • GetAdditionalActivationTagRequirements : 위에서 세팅한 데이터 에셋을 통해 Ability Activation, Block에 해당하는 태그들을 얻어옵니다.
    • TryActivateAbilitiesOnSpawn : Spawn 시 발동하는 어빌리티들을 발동합니다. 어빌리티들은 LyraGameplayAbility 타입이며 Spawn시 발동하게 끔 하는 열거형을 가집니다.
    • ClientNotifyAbilityFailed : ClinetRPC로서 아래 설명할 함수를 호출합니다.
    • HandleAbilityFailed : 어빌리티 실패 시의 동작입니다. 실패 이유와 함께 메시지 시스템을 활용하여 브로드 캐스트합니다.
  • 오버라이드한 함수
    • EndPlay : GlobalAbilitySytsem(Subsystem)에서 this ASC를 해제합니다.
    • InitAbilityActorInfo : 어빌리티들에 Avatar를 세팅하고 GlobalAbilitySystem에 this ASC를 등록하고 Spawn시 적용할 어빌리티들을 발동합니다.
    • AbilitySpecInputPressed : Input이 눌리면 AbilitySystemComponent::TargetDataMap을 통해 추가 이벤트를 발생합니다.
    • AbilitySpecInputReleased : Input이 해제되면 AbilitySystemComponent::TargetDataMap을 통해 추가 이벤트를 발생합니다.
    • NotifyAbilityActivated : Ability를 ActivationGroup에 추가합니다.
    • NotifyAbilityFailed : HandleAbilityFailed, ClientNotifyAbilityFailed를 서버, 클라에 맞게 호출합니다.
    • NotifyAbilityEnded : Ability를 ActivationGroup에서 제거합니다.
    • ApplyAbilityBlockAndCanelTags : 데이터 에셋 + 파라미터를 통해 어빌리티에 Block, Cancel Tag를 추가합니다.
  • 멤버 변수
    • TObjectPtr<ULyraAbilityTagRelationshipMapping> TagRelationshipMapping : Ability가 가지는 Tag와 가지는 관련성에 관한 정보들입니다. (데이터 에셋) ( Activation, Block, Canel, Required )
    • TArray<FGameplayAbilitySpecHandle> InputPressedSpecHandles : Input Press시 Ability의 Handle을 담아둡니다. ProcessAbilityInput을 통해 소모됩니다.
    • TArray<FGameplayAbilitySpecHandle> InputReleasedSpecHandles : Input Release시 Ability의 Handle을 담아둡니다. ProcessAbilityInput을 통해 소모됩니다.
    • TArray<FGameplayAbilitySpecHandle> InputHeldSpecHandles : Input이 계속 눌리고 있는 Handle을 담아둡니다. ProcessAbilityInput을 통해 소모됩니다.
    • int32 ActivationGroupCounts[(uint8)ELyraAbilityActivationGroup::MAX] : ActivationGroup의 숫자를 관리합니다.
  • 요약
    • LyraAbilitySystemComponent를 통해 AbilitySystemComponent의 기능에 더해 추가적인 기능을 정의했습니다.
    • LyraAbilitySystemComponent는 다음과 같은 추가 역할을 합니다.
      • Input을 개선하여 태그를 통해 Input을 가능하게 하고 Input은 모아두었다가 ProcessAbilityInput을 통해 소모됩니다.
      • 동적으로 태그를 부여하는 Effect와 메서드를 제공합니다.
      • ActivationGroup이라는 개념을 만들어 어빌리티 발동에 제약을 두었습니다.
      • 자체적인 Subsystem을 통해 ASC를 관리하며 Spawn시 부여되는 어빌리티를 쉽게 관리합니다.
      • 어빌리티의 Activation, Cancel, Block, Required에 대해 데이터 에셋의 형태로 관리할 수 있으며 태그를 통해 관리됩니다.

 

다음 글에서 LyraGameplayAbility와 AttributeSet이 어떻게 만들어져있고 적용되어있는지를 확인해보겠습니다.

 

'Unreal Engine > Lyra Starter Game 분석' 카테고리의 다른 글

[3] - Lyra Starter Game 분석  (2) 2024.04.04
[1] - Lyra Starter Game 분석  (0) 2024.04.01
[0] - Lyra Starter Game 분석  (0) 2024.04.01

+ Recent posts