TIL - ASC

조범근·2일 전

TIL

목록 보기
83/83

TIL

1. ASC

ASC는 Abililty System Component의 줄임말이고, 실제 클래스는 UAbilitySystemComponent이다. 개념적으로 ASC를 설명하자면, ACS는 GAS를 사용하는 Actor의 능력과 게임플레이 상태를 관리하는 중심 컴포넌트이다. 여기서 "능력을 관리한다"만 보면 세부적인 설명이 부족하다.

ASC는 단순히 이 캐릭터에게 "Dash"라는 스킬이 있다 정도만 기억하는 곳이 아니다. 게임을 플레이하는 동안 계속 변하는 상태까지 같이 관리한다.

예를들어서 플레이어가 현재

  • Dash 보유중
  • Dash 쿨다운중
  • 5초짜리 이동속도 증가 효과 받는중
  • Stun 상태
  • Health가 60인 상황

이라고 하자. 이것들은 서로 별개의 정보처럼 보이지만 실제 게임에서는 계속 서로 영향을 준다. 예를 들어 Dash를 가지고 있어도 Stun 상태라면 사용불가 상태일 수 있고, 특정 버프가 있으면 Dash의 성능이 달라질 수도 있다.

즉 이런 Skill의 유기적인 관계는 GAS입장에서 스킬 목록만 관리해서는 부족하다.

현재 이 Actor에게 어떤 능력이 있고, 어떤 효과가 적용되어 있고, 어떤 상태이며, 그 결과 어떤 행동을 할 수 있는지를 같이 알아야 하는 중심이 ASC이다.



2. Character가 아닌 ASC

처음 게임을 만들 때는 Character 클래스 안에서 모든 걸 처리해도 별 문제가 없어 보인다. 체력도 Character가 들고 있고, 스턴 여부도 Character가 들고 있고, Dash 쿨다운도 Character가 들고 있다고 하자. 규모가 작다면 실제로 이렇게 만들어도 된다. 문제는 기능이 늘어날때 생긴다

처음에는 체력과 Dash뿐이였는데 나중에는 Shield가 생기고, 무적이 생기고, 공격력 증가가 생기고, 이동속도 감소가 생기고, 침묵이 생기고 증강으로 스킬이 추가된다.

그러면 Character가 점점 이런 질문들을 전부 책임져야한다.

  • 지금 Dash 사용가능상태인가?
  • 지금 피해를 받을 수 있는가?
  • 현재 공격력은 얼마인가?
  • 이 버프는 언제 끝나는가?
  • Stun 상태인가? 풀렸는가?
  • 이 Ability는 플레이어에게 부여되어있는가?

결국 Character가 캐릭터 이동과 표현을 담당하는 클래스가 아니라 게임 규칙 전체를 들고 있는 거대한 GodClass가 되기 쉽다.

GAS는 이걸 분리해 Character는 캐릭터 자체의 역할을 맡고,

Ability와 GameplayEffect, Attribute, GameplayTag처럼 전투 규칙과 관련된 상태는 ASC를 중심으로 관리한다.

그래서 ASC가 하나 더 생긴게 구조 복잡화가 아닌 오히려 규모가 커졌을 때 Character가 모든 게임 규칙을 떠안지 않도록 만든 경계라고 보는 게 맞다.



3. ASC가 실제로 관리하는 것

여기서 GAS의 여러 용어가 등장하는데 깊게 들어갈 필요없이 나열만 하겠다

3-1. Ability

플레이어가 무엇을 할 수 있는가에 해당한다.

Dash, Heal, Ultimate 같은 Skill 그 자체이다. ASC는 이 Actor가 현재 어떤 Ability를 가지고 있는지 알고 있다.


3-2. Gameplay Effect

현재 Actor에게 어떤 변화가 적용되고 있는가에 해당한다.

예를 들어 이동속도 20% 증가가 5초 동안 적용된다거나, 독 피해가 일정 시간 들어오는 식이다. 만약 독 피해가 여러번 들어온다면 Stack으로 중첩 상태를 표현할 수도 있다. ASC는 이런 효과가 적용되고 제거되는 과정을 관리한다.


3-3 Attribute

Attribute의 뜻은 속성, 특징을 뜻하고 Unreal에서는 현재 Actor의 수치 상태이다.

Health, Shield, AttackPower같은 명세들이 대표적이다. 여기서 중요한 것은 ASC 자체 안에 Health라는 float 하나를 직접 만들어 놓는다는 뜻은 아니다. Attribute는 보통 AttributeSet 쪽에 정의되어 있고, ASC가 그 Attribute 시스템을 관리하고 접근하는 중심이 된다.

이 차이는 나중에 AttributeSet을 설명할 때 자세히 보면 된다.


3-4 Gameplay Tag

Unreal의 현재 Actor 상태를 이름표처럼 표현하는 정보이다.

예를 들어 플레이어가 Stun 상태라면 State.Stunned라는 Tag를 가지고 있을 수 있다. 이 때 Dash Ability에 "State.Stunned태그가 있으면 발동하지 않는다"라는 규칙 같은걸 가질 수 있다.

여기서 ASC의 재밌는 점이 ASC가 가지고 있는 각각의 정보가 따로 노는게 아니다.

Ability가 Tag를 보고 실행 여부를 결정하고, GameplayEffect가 Attribute를 변경하고, GameplayEffect 때문에 새로운 Tag가 붙을 수도 있다.

그래서 ASC를 저장소라고 보면 조금 어색하다. 여러 GAS 요소가 서로 영향을 주고받는 중심실행환경에 더 가깝다.



4. ASC의 처리 흐름

실제 게임 상황으로 ASC 역할을 보면 더 명확하다.
플레이어가 Q를 눌러 Dash를 사용한다고 하자.

입력 시스템이 Q 입력을 받음
-> GAS쪽으로 Q에 해당하는 Ability를 사용하려고 한다 라는 요청이 넘어감

여기서 중요한 건 입력 자체가 Ability를 실행하는 게 아니라는 것이다.
ASC가 중간에서 관리하고있다.
1. ASC는 우선 자신이 관리하는 Ability 중에서 이 입력과 관련된 Ability를 찾는다.
2. Ability를 찾으면 찾았다고 바로 실행하는 것도 아니라 현재 Ability를 실행할 수 있는 조건인지 판단한다.
3. Stun상태인가? 쿨다운 상태인가? 필요한 Cost를 지불할 수 없는 상태인가?
4. 조건 통과시 Ability 실행
5. Ability가 실행된 결과로 GameplayEffect가 적용되어 쿨다운이 생기거나 Attribute가 변할 수도 있다.

즉 흐름을 크게 보면

입력 → ASC → Ability 확인 및 실행 판단 → Ability 실행 → Effect/Attribute/Tag 변화

여기서 중간 관리자인 ASC가 빠지면 각각의 시스템이 직접 서로를 찾아 다녀야한다. ASC가 있으니까 "이 Actor의 GAS 상태를 확인해야 한다"라는 상황에서 바라볼 중심점이 하나 생기는 것이다.



5. ASC는 멀티에서 더 중요해진다

싱글플레이에서는 내 컴퓨터 하나에서만 상태를 맞추면 된다. 하지만 멀티플레이엇는 다르다.

서버는 "이 플레이어가 정말 이 Ability를 사용할 수 있었는가?"를 판단해야 하고,
클라이언트는 "내가 Q를 눌렀으니 즉각 반응하는 것처럼 보여야 한다."는 예측 반응 요구가 있다.

또 서버에 확정된 Ability, GameplayEffect, Tag 등의 상태가 필요한 클라이언트에게 전달되어야 한다. GAS는 이런 네트워크 문제까지 염두에 두고 설계되어 있고, ASC가 그 네트워크 처리의 핵심 단위 중 하나이다.

멀티플레이에서 중요한 Prediction Key 같은 보정시점의 기준이 되는 개념도 결국 이어진다.

클라이언트가 예측반응으로 스킬을 사용 하게되면, 나중에 서버 결과와 맞추는 과정인 보정이 필요한데 그 예측 상태 역시 GAS와 ASC의 실행 흐름 안에서 관리된다. 너무 깊게 들어가면 ASC 설명의 본분에서 멀어지므로 여기서는

ASC는 로컬 상태 저장소가 아니라 멀티플레이 GAS 상태를 동기화하는 중심이기도 하다.

정도로 알아두자



6. 멀티에서 ASC의 장소

ASC는 반드시 Character에 붙어 있어야 하는 컴포넌트가 아니다. 어떤 Actor가 ASC를 소유할지는 게임 구조에 따라 정할 수 있다. 멀티플레이 게임에서는 ASC를 PlayerState에 두는 구조가 흔히 사용된다. 이 이유는 Character가 죽어서 없어지고 새로 Spawn될 수 있기 때문이다.

예를 들어 플레이어가 죽는다. -> Character가 Destory되고 잠시 뒤 새로운 Character 생성
-> 이때 ASC가 이전 Character에 붙어 있었다면? Character가 사라질때 ASC수명도 같이 생각해야한다.

반면 PlayerState는 일반적으로 플레이어 자체의 상태를 유지하기 위해 Character보다 오래 살아 있다. 그래서 PlayerState가 ASC를 소유하고, 현재 Character가 그 ASC를 사용하는 구조를 만들 수 있다. 이러면 Character가 Respawn되더라도 플레이어의 GAS 시스템을 이어가기 편해진다.



7. 결론 ASC의 정의

ASC를 Ability를 저장하는 컴포넌트라고 기억하기에는 너무 좁은 개념이고, 이렇게 단순하지도 않다. 반대로 GAS의 모든 것은 너무 추상적이다.

ASC는 이 Actor가 현재 무엇을 관리할 수 있고, 어떤 게임플레이 상태에 있으며, 그 상태가 어떻게 변하고 있는지를 GAS 방식으로 관리하는 중간 관리자역할이다.

그래서 Ability를 찾으려 해도 ASC를 보고, 현재 GameplayEffect를 확인하려 해도 ASC를 보고, Tag를 확인하려 해도 ASC를 보고, Attribute 변화 이벤트를 받으려고 해도 ASC로 들어간다.

0개의 댓글