ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Unreal] Game Ability System, GAS를 써본 후기
    쾌락없는 책임 (공부)/Unreal 2025. 9. 2. 12:12
    반응형

    모듈화에 힘을 쓰는 에픽

    최근 들어 언리얼 개발자에게 있어서는 Game Ability System, 통칭 GAS의 이야기가 많이 오가고 있습니다. 이 기본 시스템을 통해 많은 것들을 확장성 좋게 만드냐, 아니면 너무 과하게 구현되어 있어 최적화의 여지가 필요하다 등 저도 이러저러한 이야기들을 많이 들었습니다.

     

    이야기를 듣기만 했을 때는 확실히 에픽의 기조가 '모듈화'로 기울었다는 생각이 듭니다. 회사에서 구세대 엔진인 언리얼 3을 해서 더 그렇게 느끼는지는 모르겠으나 컴포넌트화부터 해서 플러그인들까지 점점 모듈화에 힘쓰는 거 같습니다. 좋게 이야기되면 모듈화고 나쁘게 이야기하면 파편화가 될 수 있는데 실제로는 어떠할지 직접 경험한 것들을 이야기해 보려고 합니다.

     

     

    에픽의 샘플들을 보았을 때 - Lyra, Titan 

    최근 에픽 게임즈의 언리얼 엔진 샘플들을 보면 대부분의 경우 GAS 를 활용해 프로젝트를 제작하였습니다. 특히 Lyra(이하 라이라)에서 많은걸 볼 수 있어 다들 참고하는 것 같습니다. 

     

    일단 라이라 에서는 기본 총기 동작이라던가 대시 등에 대해서 어빌리티로 구현을 하였는데 각종 태그들을 함께 활용하면서 게임에서 사용할 때의 장점을 알려주었습니다. 재장전 중에 태그를 추가해 발사 등의 로직이 들어갈 수 없게 하는 등의 것들을 볼 수 있었습니다. 멀티플레이에서도 사용 가능하다는 걸 보여준 프로젝트로 GAS를 보기 위해서는 알아가야 하는 프로젝트라 생각됩니다. Titan(이하 타이탄)

     

    그런데 '슈팅 게임용이냐?' 라고 하면 GAS는 슈팅 게임용은 아닌 것 같습니다. 정확히는 총기 기능에 대해서는 GAS를 쓰지 않는 게 맞았을 것 같습니다.

    • '총 발사가종료되었냐'를 알아야 하는데 라이라의 GAS로는 알기 어렵습니다.
      • 연사가 한 어빌리티에서 계속 진행하는 것이 아니라 단일 발사를 계속 활성화하는 것이라 라이라 샘플로는 알 수 없습니다
      • 총기 발사 종료 시의 작업을 언제 진행할지 알 수 없어(총열 이펙트, 반동 돌아오기 등) FPS, TPS에서는 개량이 필요해 보입니다. 
    • 데미지용 GameplayEffect에서 무기의 공격력을 가져오지 않는 상태라 무기별 버프/디버프등이 섞이는 경우 GameplayEffect의 코드가 난잡해질 우려가 있습니다. 
    • 타이탄 프로젝트에서 UI 버튼 누르는 동작까지 어빌리티로 만들었는데 '이렇게까지 해야 하나' 는 생각이 듭니다. 

     

    사실 첫 이유가 가장 크지 않을까 해서 슈팅 게임에서는, 적어도 총기에서는 GAS를 사용하지 않는 것이 더 좋아 보입니다. 특히 라이라 샘플의 경우 무기도 파츠하나 없는 단일 무기에 장착/해제 시 SpawnActor/Destroy를 하는 괴랄한 구조를 탄생시켰기에... 성능에 민감하거나 총기 로직이 복잡하다면 라이라는 참고 정도만 하는 게 좋아 보입니다.

     

    총기를 제외한 스킬, 능력 등에 대해서는 어빌리티를 활용하여도 괜찮을 것 같습니다. 다만 시스템의 일관성이 지켜지지 않다보니 프로젝트가 장기적으로 가는 경우 섞어서 사용했을 때 코드가 더러워질 우려가 있을 것 같네요.

     

    사이드 프로젝트(생존 RPG)에서의 GAS

    단 슈팅게임을 벗어나면 GAS 는 이야기가 달라질 정도로 유용하게 사용됩니다.

     

    보통 이런 게임에서 지닌 무기에 따라 행위가 달라지고 이에 따른 Input 이 달라지게 됩니다. 복잡한 아이템은 요구되는 Input 이 많아질 수도 있죠. 원래대로라면 Input에 따른 키 바인딩을 추가하기 위해 여러 함수들이 제작되고 바인딩되었을 텐데 어빌리티를 활용하면 지닌 무기에 따라 어빌리티를 동적으로 주고/거두고 하는 방식으로 간소화할 수 있습니다. 쓸데없는 Input에 대한 예외처리를 하지 않고, 필요한 Input 만 처리하는 방식이 가능한 거죠.

     

    또 생존 게임에서는 행동들이 많이 요구됩니다. 낚시나 앉기, 쉬기, 아이템 상호작용 등 여러 일들이 많은데 이것들을 전부 Character에 넣기에는 Character 코드가 난잡해질 것이고, 컴포넌트화를 하자니 컴포넌트가 너무 많아져 매한가지고. 이런 경우 어빌리티를 활용하면 각 '행동'에 대해서 클래스들이 따로 만들어지기에 생성, 유지보수가 한결 간편해진다는 느낌이 들었습니다. Tag를 통해 트리거하는 시스템을 만들어두면 UI나 이벤트, 상호작용 등에서도 잘 사용하기도 해 이런 RPG 게임에서는 어빌리티로 관리하는 게 확실히 편했습니다.

     

    또한 AI Behavior Tree를 만드는 데 있어서 ASC 기반의 AI Pawn 이 만들어지면 BT Task 가 가벼워집니다. 공격을 한다고 할 때 해당하는 어빌리티를 AI에게 쥐어준 뒤 Tag 이벤트를 트리거 해 공격을 활성화할 수 있거든요. 이전 BT에서 공격을 하기 위해서는 AI에서 공격 인터페이스를 제작한 뒤 BT Task를 통해 해당 인터페이스를 부르는 등 여러 작업이 추가되었었습니다. 그런데 어빌리티를 기반해 행동들을 정의하면 BT Task 작업도 상대적으로 적다는 게 체감됩니다. 

     

    다만 여전히 단점은 존재합니다. GAS에서 따라오는 Attribute 시스템이 있습니다. 보통 체력같이 능력치를 나타내는 데 사용하는 시스템인데 Gameplay Effect와 연계하면 편하게 아이템 효과, 대미지 등이 제작 가능합니다. 다만 해당하는 Attribute를 리플리케이트 할 때 Listen-Server(생존게임이라 해당 서버 형태도 고려 중입니다)라면 RepNotify를 주는 게 좀 귀찮아집니다. 잘못 코드를 작성하면 Listten-Server에서 노티파이의 무한루프에 빠져서 추적하기도 어려웠던 기억이 있습니다.

     

    // Listen-Server 에서 Authority(ListenServer) 가 있는 상태에서 Notify 를 호출하면 무한루프에 빠집니다
    // 이를 위해 OnRep 함수를 부를 때 Notify를 호출할지의 조건을 체크합니다
    // 매크로로 한 이유는 코드가 너무 길어져서...
    
    #define REPLICATE_IF_NOT_AUTHORITY(Attribute, OldValue) \
    if (GetOwningActor() && !GetOwningActor()->HasAuthority()) \
    { \
    	GAMEPLAYATTRIBUTE_REPNOTIFY(UPlayerAttributeSet, Attribute, OldValue); \
    }
    
    void UPlayerAttributeSet::OnRep_Stamina(const FGameplayAttributeData& OldStamina)
    {
    	REPLICATE_IF_NOT_AUTHORITY(Stamina, OldStamina);
        if (GetStamina() <= 0.0f)
        {
            SetSprinting(false);
        }
        StaminaAttributeChangedEvent.Broadcast(OldStamina.GetCurrentValue(), GetStamina());
        OnStaminaChangedEvent.Broadcast(GetMaxStamina(), GetStamina());
    }

     

    실제로 제 프로젝트에서는 Listen-Server인 경우에 Notify를 주기 위해서 이런 예외처리를 계속해야 하는 문제도 있었습니다. DS에서는 이 정도로 고려하지는 않지만 Listen-Server를 제작하시는 분들에게는 음... Attribute를 자체적으로 하는 게 더 나을 수도 있겠다는 생각이 들게 됩니다.

     

     

    결론

    일단 그래도 몇몇 사용처에서 GAS를 사용해 본 이야기를 해 보았습니다. 장르에 따라서 해당 기능을 넣을까 말까에 대한 고민을 하시는 분들에게 조금이나마 도움이 되었으면 합니다. 각자 직접 사용해 보는 후기가 제일 체감이 되겠지만 시간이 없으니 이런 후기를 찾아보시는 분들에게 도움이 되었으면 합니다.    

    반응형

    댓글

Designed by Tistory.