게임플레이 어빌리티 시스템 은 액터가 소유하고 트리거할 수 있는 어빌리티 및 인터랙션을 빌드하기 위한 프레임워크입니다. 이 시스템은 캐릭터가 메커니즘, 비주얼 이펙트, 애니메이션, 사운드, 데이터 기반 엘리먼트를 조정해야 하는 어빌리티를 가지고 있는 RPG, 액션 어드벤처 게임, MOBA 등의 게임 타입을 위해 디자인되었지만 다양한 프로젝트에서 이 시스템을 도입할 수 있습니다. 게임플레이 어빌리티 시스템은 또한 멀티플레이어 게임을 위한 리플리케이션을 지원하고 개발자가 멀티플레이어를 지원하기 위해 디자인을 스케일링 업하는 시간을 크게 줄여줍니다.
이 시스템을 사용하면 단일 공격처럼 간단한 어빌리티나 사용자 및 타깃의 데이터에 따라 다양한 상태 이펙트를 트리거하는 스펠과 같은 복잡한 어빌리티를 생성할 수 있습니다. 이 페이지에서는 어빌리티 시스템의 개요와 어빌리티 시스템의 여러 컴포넌트가 함께 작동하는 방식을 살펴봅니다.
게임플레이 어빌리티란?
게임플레이 어빌리티 는 액터가 소유하고 반복적으로 트리거할 수 있는 인게임 액션입니다. 일반적인 예시로는 스펠, 특수 공격, 아이템이 트리거하는 이펙트 등이 있습니다. 이 개념은 비디오 게임에서 매우 일반적입니다. 어빌리티를 실행하는 프로세스는 복잡하고 특정한 타이밍을 요구하는 경우가 많음에도 불구하고 이러한 어빌리티를 당연하게 여기는 경우가 많습니다. 예를 들어 공격 활성화 코드를 작성하는 것은 비교적 간단하지만 장기간에 걸쳐 프로젝트를 진행하는 동안에는 플레이어에서 콤보 시스템이나 다른 디테일을 추가 또는 제거하기 위해 리소스 비용, 버프, 디버프 이펙트를 추가함에 따라 어빌리티를 빌드하는 복잡도가 기하급수적으로 늘어날 수 있습니다. 따라서 언리얼 엔진의 게임플레이 어빌리티 시스템은 다음과 같은 세 가지 주요 사항을 고려하여 디자인되었습니다.
어빌리티의 오너 트래킹하기
어빌리티와 이펙트는 소유권이라는 개념을 유지해야 합니다. 이펙트가 계산을 수행할 때는 오너가 누구인지 알아야 어트리뷰트를 사용할 수 있습니다. 어빌리티가 플레이터의 포인트를 기록하는 작업을 할 때는 포인트를 소유한 플레이어가 누구인지 알아야 크레딧을 정확하게 부여할 수 있습니다.
게임플레이 어빌리티의 '오너'는 네트워크 리플리케이션 용어에서 사용되는 소유권의 그것과는 다릅니다.
어빌리티의 스테이트 트래킹하기
어빌리티는 다음과 같은 스테이트 순환을 트래킹할 수 있어야 합니다.
- 어빌리티가 활성화된 시점
- 어빌리티의 실행이 현재 진행 중인 시점
- 어빌리티가 완전히 완료되고 더 이상 활성회되지 않은 시점
라이라 샘플 프로젝트 또한 어빌리티가 부여되는 시점을 트래킹합니다.
예를 들어 일반적으로 어빌리티를 사용하는 동안 액터는 어빌리티의 사용을 완료하기 전까지 해당 어빌리티를 다시 활성화할 수 없습니다. 하지만 어빌리티는 실행을 일찍 종료한 다음 다시 시작하여 어빌리티를 취소 하는 것을 가능하도록 하는 특별한 규칙을 가질 수 있습니다.
어빌리티의 실행 조정하기
어빌리티는 실행 도중 특정한 타이밍에 다양한 시스템과 인터랙션할 수 있어야 합니다. 이러한 인터랙션의 예시는 다음과 같습니다.
-
애니메이션 몽타주를 활성화하기
-
캐릭터의 무브먼트를 일시적으로 제어하기
-
비주얼 이펙트 트리거하기
-
오버랩 및 콜리전 이벤트 수행하기
-
일시적으로 또는 영구적으로 캐릭터의 통계 변경하기
-
인게임 리소스를 늘리거나 줄이기
-
다른 어빌리티의 활성화를 허용 또는 차단하기
-
어빌리티 사용을 제한하기 위해 쿨다운 처리하기
-
인게임 이벤트에 의한 중단
-
진행 중인 다른 어빌리티 취소하기
-
새로운 무브먼트 모드를 활성화하는 등 캐릭터에 주요 스테이트 변경사항 적용하기
-
다른 인터랙션 도중 입력에 반응하기
-
UI 요소를 업데이트하여 어빌리티의 인게임 상태 표시하기
어빌리티가 작동하는 방식에 따라 활성화되어 있는 동안 애니메이션이 재생되는 동안을 포함하여 시간상 여러 지점에서 이러한 인터랙션을 수행할 수 있습니다. 일부 이펙트는 어빌리티가 완료된 후에도 지속될 필요가 있습니다.
게임플레이 어빌리티 시스템의 컴포넌트
게임플레이 어빌리티 시스템은 어빌리티를 자체 실행에 반응하는 독립적인 엔티티로 모델링하여 이러한 사용 사례를 모두 처리할 수 있도록 디자인되었습니다. 이 시스템은 다음과 같은 컴포넌트로 구성되어 있습니다.
-
액터가 소유하고 활성화를 처리하는 모든 어빌리티의 목록을 유지 관리하는 어빌리티 시스템 컴포넌트 를 갖춘 소유 액터
- 각 어빌리티를 나타내고 인게임 실행을 조정하는 게임플레이 어빌리티 블루프린트
- 다른 함수와 함께 게임플레이 어빌리티 작업 으로 구성된 컴포넌트
- 어빌리티 시스템 컴포넌트에 어태치된 어트리뷰트 세트
- 계산을 구동하거나 리소스를 나타내는 게임플레이 어트리뷰트 를 포함하는 컴포넌트
- 어빌리티를 사용한 결과로 인해 액터에 발생한 변경사항을 처리하는 게임플레이 이펙트
- 이펙트 계산을 위해 재사용 가능한 모듈형 메서드를 제공하는 게임플레이 이펙트 계산
- 게임플레이 이펙트와 연관되어 있으며 비주얼 이펙트를 처리하기 위한 데이터 기반 메서드를 제공하는 게임플레이 큐
아래 섹션에서는 이러한 클래스를 자세하게 살펴봅니다.
소유권 트래킹하기
게임플레이 어빌리티를 사용하려면 액터에 어빌리티 시스템 컴포넌트를 어태치해야 합니다. 이 컴포넌트는 액터에 어빌리티를 추가 및 제거하고, 액터가 소유한 어빌리티가 무엇인지 지속적으로 트래킹하고, 이를 활성화합니다. 또한 어빌리티 시스템의 컨텍스트에서 소유 액터를 나타내는 주요 수단으로서 어트리뷰트, 진행 중인 이펙트, 게임플레이 태그 , 게임플레이 이벤트 를 위한 시스템과 소유 액터에 직접 액세스하기 위한 인터페이스를 제공합니다.
멀티 플레이어 게임에서 어빌리티 시스템 컴포넌트는 클라이언트에 정보를 리플리케이트하고, 서버에 플레이어 액션을 전달하고, 클라이언트가 어빌리티 시스템 컴포넌트의 스테이트를 변경할 권한이 있는지 확인합니다. 어빌리티 시스템 컴포넌트의 부모 액터는 원격 활성화를 수행하기 위해 로컬에서 제어되는 플레이어가 소유해야 합니다.
어빌리티 및 실행 처리하기
게임플레이 어빌리티는 애니메이션 재생, 이펙트 트리거, 오너에서 어트리뷰트 가져오기, 비주얼 이펙트 표시를 포함하여 어빌리티의 모든 이벤트를 실행하는 것을 담당하는 블루프린트 오브젝트입니다.
활성화 제어하기
게임플레이 어빌리티는 다음과 같은 네 가지 주요 메서드를 통해 활성화 할 수 있습니다.
-
블루프린트 또는 C++를 통해 게임플레이 어빌리티 핸들 을 사용하여 어빌리티를 명시적으로 활성화할 수 있습니다. 이는 어빌리티가 부여될 때 어빌리티 시스템 컴포넌트에 의해 제공됩니다.
-
게임플레이 이벤트를 사용합니다. 이는 일치하는 어빌리티 트리거로 모든 어빌리티를 실행합니다. 입력 및 결정 메커니즘을 추상화해야 하는 경우 유연성을 극대화하기 위해서는 이 메서드를 사용하는 것이 좋습니다.
-
일치하는 태그와 함께 게임플레이 이펙트를 사용합니다. 이는 일치하는 어빌리티 트리거로 모든 어빌리티를 실행합니다. 게임플레이 이펙트의 트리거 어빌리티를 끄려는 경우 선호되는 메서드입니다. 일반적인 사용 사례는 비활성화된 애니메이션을 재생하고 다른 게임 액션을 차단하는 어빌리티를 트리거하는 슬립 디버프입니다.
게임플레이 어빌리티는 다양한 배열의 인게임 액션을 나타내며 플레이어가 명시적으로 사용하는 힘이나 스펠에 제한되지 않습니다. 히트 반응 또는 앞서 언급한 슬립 애니메이션이 좋은 예시입니다.
- 입력 코드 를 사용합니다. 입력 코드는 어빌리티 시스템 컴포넌트에 추가되어 있으며 호출 시 일치하는 모든 어빌리티를 트리거합니다. 이 함수는 게임플레이 이벤트와 유사합니다.
게임플레이 어빌리티를 활성화 할 경우 시스템은 어빌리티가 진행 중인 것으로 인식합니다. 그런 다음 활성화 이벤트에 어태치된 코드를 실행하여 완료 함수를 호출해 어빌리티의 실행이 완료되었음을 알리기 전까지 각 함수와 게임플레이 작업을 거쳐 이동합니다. 정리 작업을 추가로 진행해야 하는 경우 완료 시 이벤트에 코드를 추가로 어태치할 수 있습니다. 또한 어빌리티를 취소 하여 실행을 중단할 수 있습니다.
게임플레이 어빌리티는 게임플레이 태그를 사용하여 실행을 제한합니다. 모든 어빌리티는 활성화될 때 소유 액터에 추가하는 태그의 목록과 더불어 활성화를 차단하거나 어빌리티를 자동으로 취소하는 태그의 목록을 가지고 있습니다. 자체 코드로 어빌리티의 실행을 수동으로 취소, 차단, 허용할 수 있지만 이는 시스템적으로 일관된 메서드를 제공합니다.
실행 제어하기
게임플레이 어빌리티는 쿨다운 및 리소스 비용 할당과 같이 일반적으로 사용되는 다양한 사용 사례를 지원하며, 애니메이션 및 기타 일반적인 언리얼 엔진 시스템을 처리하는 사전 제작된 게임플레이 어빌리티 작업 라이브러리가 제공됩니다.
표준 블루프린트 함수 노드가 실행을 즉시 종료할 때 게임플레이 어빌리티 작업은 노드가 비활성인지, 진행 중인지, 완료되었는지를 계속 트래킹하며 실행 도중 다른 이벤트를 실행하도록 프로그래밍할 수 있습니다. 또한 부모 게임플레이 어빌리티가 적절하게 취소되고 정리되었는지 지속적으로 트래킹할 수 있습니다. 게임에서는 게임플레이 어빌리티 작업을 확장하여 커스텀 게임플레이 로직을 구현하는 것이 일반적입니다.
게임플레이 어빌리티는 소유 액터에서 게임플레이 태그와 이벤트 데이터 구조체를 수신하기 위해 대기하는 일반 이벤트 리스너인 게임플레이 이벤트에 응답할 수 있습니다.
어트리뷰트 세트 및 어트리뷰트
게임플레이 어트리뷰트 시스템은 주로 게임플레이 어트리뷰트 를 포함하는 어트리뷰트 세트 를 통해 액터와 인터랙션합니다. 이러한 어트리뷰트 세트는 계산에 사용되거나 게임플레이 어빌리티에 의해 수정될 수 있는 부동 소수점 값입니다. 이러한 값은 원하는 목적에 따라 사용할 수 있지만 캐릭터의 체력, 히트 포인트, 힘 및 지능 같은 캐릭터의 핵심 통계 값을 트래킹하는 데 일반적으로 사용됩니다. 이러한 값을 나타내기 위해 기본 변수를 사용할 수 있지만 게임플레이 어트리뷰트는 몇 가지 이점을 제공합니다.
-
어트리뷰트 세트는 시스템을 빌드할 수 있는 일관되고 재사용 가능한 어트리뷰트 그룹을 제공합니다.
-
게임플레이 어빌리티는 리플렉션을 통해 게임플레이 어트리뷰트에 액세스할 수 있으므로 블루프린트 에디터에서 직접 간단한 계산과 이펙트를 생성할 수 있습니다.
-
게임플레이 어트리뷰트는 디폴트 값, 현재 값, 최대 값을 별도로 트래킹하여 일시적인 수정(버프 및 디버프) 및 지속적인 이펙트를 손쉽게 생성할 수 있습니다. 게임플레이 어트리뷰트는 또한 값을 모든 클라이언트에 리플리케이트하며 적 체력 표시줄 같은 로컬 UI 시각화에 안전합니다.
액터에 게임플레이 어빌리티를 사용하려면 어빌리티 시스템 컴포넌트에 어트리뷰트 세트를 추가해야 합니다. 이렇게 하면 어빌리티 시스템 컴포넌트는 어트리뷰트 세트에 할당된 어트리뷰트에 자동으로 액세스할 수 있습니다.
게임플레이 이펙트 처리하기
게임플레이 어빌리티 시스템은 게임플레이 이펙트를 사용하여 게임플레이 어빌리티에서 타기팅한 액터에 변경사항을 적용합니다. 이는 대미지를 적용하거나, 지속적인 독 대미지, 버프, 디버프와 같이 지속되는 이펙트를 적용하는 원샷 이펙트일 수 있습니다. 지속적인 이펙트의 경우 게임플레이 이펙트는 제거될 때까지 타깃 액터에 자신을 어태치합니다. 만료되거나 정리되기 전까지로 제한된 수명을 미리 설정할 수 있고 타깃 액터의 게임플레이 어트리뷰트에 적용된 변경사항을 실행 취소할 수 있습니다.
게임플레이 이펙트는 게임플레이 이펙트 계산을 사용하여 게임플레이 어트리뷰트에 기반하여 계산을 처리합니다. 블루프린트 에디터에서 간단한 계산을 직접 생성할 수 있지만 보다 복잡한 로직을 가지고 있으며 다수의 어트리뷰트에 동시에 영향을 미치는 커스텀 이펙트 계산을 프로그래밍할 수 있습니다. 이는 게임플레이 어빌리티의 소유 액터와 타깃 액터 모두에서 정보를 처리할 수 있어 일반적으로 이뤄지는 계산을 재사용 가능한 일련의 코드로 결합할 수 있습니다.
장식 이펙트 처리하기
게임플레이 큐는 비주얼 이펙트와 사운드 이펙트 실행을 담당하는 액터 및 UObject이며 멀티플레이어 게임에서 장식 피드백을 리플리케이트하는 데 선호되는 메서드입니다. 게임플레이 큐를 생성할 때는 '이벤트 그래프(Event Graph)' 내에서 재생할 이펙트를 위한 로직을 실행합니다. 게임플레이 큐는 일련의 게임플레이 태그와 연관될 수 있으며 이러한 태그와 일치하는 게임플레이 이펙트는 자동으로 적용됩니다.
예를 들어 게임플레이 큐에 Ability.Magic.Fire.Weak 태그를 추가하면 Ability.Magic.Fire.Weak를 가지고 있는 게임플레이 이펙트가 해당 게임플레이 큐를 자동으로 스폰하여 실행합니다. 이를 통해 코드에서 수동으로 트리거할 필요 없이 비주얼 이펙트의 유니버설 라이브러리를 손쉽고 빠르게 생성할 수 있습니다.
또는 게임플레이 이펙트의 관여 없이 큐를 트리거할 수 있습니다. 이 구현의 예시로 라이라 샘플 게임의 무기 발사 피드백을 참고할 수 있습니다.
게임플레이 큐는 신뢰할 수 있는 리플리케이션을 사용하지 않기 때문에 일부 클라이언트가 큐를 수신하지 못하거나 피드백을 표시하지 못하는 경우가 있습니다. 게임플레이 코드에 결합되어 있는 경우 이로 인해 동기화가 해제될 수 있습니다. 따라서 게임플레이 큐는 장식 피드백에만 사용해야 합니다. 모든 클라이언트에 리플리케이트되어야 하는 게임플레이 관련 피드백의 경우에는 리플리케이션을 처리하기 위해 어빌리티 작업에 대신 의존해야 합니다. 몽타주 재생 어빌리티 작업은 이의 좋은 예시입니다.
네트워크 멀티플레이어 지원하기
게임플레이 어빌리티는 네트워크 멀티플레이어 게임을 지원하기 위한 내장 함수 기능을 제공하지만 몇 가지 제약이 있으며 유의해야 하는 가이드라인이 있습니다. 이러한 가이드라인의 대부분에는 일반 네트워크 멀티플레이어 모범 사례가 반영되어 있습니다.
어빌리티 시스템 컴포넌트 및 리플리케이션
대역폭을 절약하고 부정 행위를 방지하려면 어빌리티 시스템 컴포넌트가 모든 클라이언트에 전체 스테이트를 리플리케이트하지 않아야 합니다. 모든 클라이언트에 어빌리티와 게임플레이 이펙트를 리플리케이트하지 않고 영향을 받는 게임플레이 어트리뷰트와 태그만 리플리케이트해야 합니다.
어빌리티 리플리케이트 및 예측 사용하기
네트워크 게임의 어빌리티 대부분은 서버에서 실행되고 클라이언트로 리플리케이트되어야 합니다. 따라서 어빌리티 활성화에 지연이 발생하는 것은 일반적인 현상입니다. 하지만 이러한 지연은 빠른 속도로 진행되어야 하는 대부분의 멀티플레이어 게임에서 바람직하지 않습니다. 이러한 지연을 최소화하려면 어빌리티를 로컬로 활성화한 다음 활성화한 사실을 서버에 알리고 서버에서 이를 따라잡을 수 있게 해야 합니다.
서버가 어빌리티 활성화를 거부하는 경우가 있을 수 있습니다. 이 경우에는 어빌리티가 로컬로 적용한 변경사항을 실행 취소해야 합니다. 로컬로 예측된 어빌리티를 사용하여 이러한 경우를 처리할 수 있습니다. 이를 지원하기 위해 이펙트를 부여한 어빌리티가 서버에 의해 거부된 경우 일부 게임플레이 이펙트에서 롤백을 지원합니다. 여기에는 대부분의 즉각적이지 않은 GE가 포함되며, 대미지 및 즉각적인 기타 어트리뷰트/태그 변경사항은 제외됩니다.
서버가 소유한 오브젝트와 인터랙션하기 위해 어빌리티 사용하기
게임플레이 어빌리티는 봇, NPC, 서버 소유의 기타 액터 및 오브젝트와의 인터랙션을 처리할 수 있습니다. 이는 로컬로 소유된 액터(주로 플레이어의 폰) 및 리플리케이트된 어빌리티 또는 서버 함수를 호출하는 기타 비GAS 메커니즘을 통해 수행해야 합니다. 이는 인터랙션을 서버에 리플리케이트한 다음 NPC와의 변경사항을 수행하는 권한을 가집니다.
추가 참고 자료
게임플레이 어빌리티 시스템의 실제 작동 모델을 살펴보려면 몇 가지 어빌리티와 무기를 도입한 라이라 샘플 게임 프로젝트를 참고하세요. 이러한 빌딩 블록을 사용하여 직접 작업해 보려면 게임플레이 어빌리티 시스템 퀵스타트 가이드를 따르면 됩니다.