UE5 Motion Matching 3편 :: 전투 애니메이션... 그리고 GAS 연동

2026. 3. 14. 23:00·Dev./UE 언리얼 엔진

지금 프로젝트에서 전투는 어디에서 결정되는가

 

UE5 Motion Matching 1편 :: 모든 캐릭터가 이동 시스템을 공유하는 구조

Unreal Engine 5.7 | Motion Matching | Pose Search | Chooser Table | AnimInstance 아키텍처캐릭터가 셋인데 이동 시스템은 하나여야 한다검사, 방패병, 궁수. 이 세 캐릭터는 무기도 다르고, 전투 스타일도 다르다.

raindrovvv.tistory.com

 

UE5 Motion Matching 2편 :: Offset Root Bone, Warping, IK, Aim Offset

Motion Matching이 모션을 골랐다. 그 다음은?2026.03.11 - [Dev./UE 언리얼 엔진] - UE5 Motion Matching 1편 :: 모든 캐릭터가 이동 시스템을 공유하는 구조 UE5 Motion Matching 1편 :: 모든 캐릭터가 이동 시스템을 공

raindrovvv.tistory.com

1편에서 Motion Matching 기반 공통 이동 계층의 구조를 다루었고,

2편에서 Offset Root Bone, Warping, IK, Aim Offset을 세팅하는 과정을 다루었다.

여기까지가 "캐릭터가 자연스럽게 이동하는 것"이다.

 

이 프로젝트는 전투 게임이다.

캐릭터는 칼을 휘두르고, 굴러서 회피하고, 포션을 마시고, 피격당하면 경직되고, 활 시위를 당기고, 궁극기를 사용한다.

이 모든 행동은 Motion Matching이 재생하는 locomotion 위에 Montage로 덮어씌워진다.


현재 구조를 한 문장으로 요약하면

지금 프로젝트의 전투 연동은 다음 흐름으로 이해하는 것이 가장 안전하다.

Enhanced Input
    -> 입력 태그 바인딩
    -> UGS_AbilitySystemComponent
    -> GameplayAbility 활성화
    -> GameplayTag / GameplayEffect / 이동 / 타격 처리
    -> 필요 시 애니메이션 자산이 시각 표현 담당

입력은 Enhanced Input에서 ASC로 바로 들어간다

현재 프로젝트에서 플레이어 입력은 FGS_ExtensionExecute_BindInput_TPS가 묶는다.

여기서 중요한 점은 두 가지다.

  1. NativeInputActions는 이동과 시선 같은 기본 조작으로 연결된다.
  2. AbilityInputActions는 InputTag를 통해 UGS_AbilitySystemComponent로 바로 전달된다.
Input Action Triggered
    -> Input_AbilityPressed(InputTag)
    -> ASC::AbilityInputTagPressed(InputTag)

Input Action Completed
    -> Input_AbilityReleased(InputTag)
    -> ASC::AbilityInputTagReleased(InputTag)

그 다음 실제 활성화는 UGS_AbilitySystemComponent::ProcessAbilityInput()에서 처리된다.

 

여기서 각 어빌리티의 ActivationPolicy를 보고 OnInputTriggered인지 WhileInputActive인지 구분해서 활성화한다. 이 구조 덕분에 입력 계층은 "무슨 키를 눌렀는가"만 알고, 실제 전투 행동은 Ability가 가져간다.


ASC의 수명 주기는 PlayerState 중심이다

플레이어의 ASC는 캐릭터가 아니라 AGS_PlayerState가 소유한다.

이 점은 지금 구조를 이해할 때 중요하다.

  • AGS_PlayerState는 UGS_AbilitySystemComponent를 생성한다.
  • 같은 곳에서 UGS_VitalAttributeSet, UGS_CombatAttributeSet, UGS_MovementAttributeSet도 함께 가진다.
  • AGS_PlayerCharacter는 PossessedBy()와 OnRep_PlayerState()에서 InitAbilityActorInfo()를 호출해 PlayerState의 ASC를 자기 자신 아바타에 연결한다.

즉 플레이어 전투 데이터의 중심은 Pawn이 아니라 PlayerState다.

 

이 구조는 멀티플레이어에서 자연스럽다. Pawn은 바뀔 수 있지만,

플레이어의 상태와 스킬 시스템은 PlayerState 쪽에 살아있다.


Ability 베이스 클래스가 전투의 성격을 결정한다

현재 공용 베이스인 UGS_GameplayAbility는 두 가지 기본값을 가진다.

  • InstancedPerActor
  • ServerOnly

이 설정은 곧 프로젝트의 전투 철학을 보여 준다.

  1. 능력은 액터 단위 인스턴스로 관리한다.
  2. 실제 게임플레이 영향은 서버 권한에서 처리한다.

그래서 지금 코드에서 보이는 핵심 전투 로직은 대부분 "클라이언트가 애니메이션 프레임에서 무엇을 했는가"보다

"서버가 어떤 Ability를 실행했고 어떤 Tag와 Effect를 적용했는가"에 가깝다.


지금 확인되는 전투 Ability 패턴

현재 C++ 트리에서 전투 흐름을 가장 분명하게 보여 주는 Ability는 다음 부류다.

1. 이동/상태 부여형 Ability

UGS_GA_Roll은 구르기를 Montage 중심으로 풀지 않는다.

이 Ability는 다음 순서로 동작한다.

  1. CommitAbility()
  2. LaunchCharacter()로 회피 이동
  3. 서버에서 State.Invincible, State.Rolling 태그 부여
  4. 타이머 종료 후 태그 제거
  5. EndAbility()

즉 현재 구현에서 롤링은 "구르기 몽타주를 얼마나 정교하게 재생하느냐"보다 상태 태그와 이동 처리가 먼저다.

2. 자기 자신에게 효과를 거는 Ability

UGS_GA_Merci_EagleEye는 자동조준 모드를 켠다.

이 Ability는 전용 GameplayEffect를 자기 자신에게 적용하고, 일정 시간이 지나면 그 이펙트를 제거한 뒤 종료한다.

여기서 중요한 것은 Draw/Aim Montage보다 상태를 이펙트와 태그로 유지한다는 점이다.

3. 타격을 직접 처리하는 Ability

현재 여러 공격 Ability는 Notify보다 Ability 내부에서 직접 판정을 낸다.

  • UGS_GA_BasicAttack
  • UGS_GA_Ares_ChargeDash
  • UGS_GA_Chan_ShieldSlam
  • UGS_GA_Chan_WarCry
  • UGS_GA_Merci_MultiShot
  • UGS_GA_Merci_SmokeArrow
  • 드라카(보스 몬스터)와 몬스터 계열 Ability들

이들의 공통 패턴은 비슷하다.

  1. 타깃을 Trace나 충돌, 혹은 스폰된 액터 기준으로 찾는다.
  2. 대상의 ASC를 가져온다.
  3. GameplayEffectSpec를 만든다.
  4. ApplyGameplayEffectSpecToTarget() 혹은 ApplyGameplayEffectSpecToSelf()를 호출한다.

즉 현재 기준으로 데미지와 버프/디버프의 실제 적용 시점은 대부분 Ability 코드 안에 있다.


Combo는 "완성된 전투 시스템"보다 "골격이 먼저 들어온 상태"에 가깝다

현재 프로젝트에는 Combo 관련 태그와 ASC 지원 코드가 이미 들어와 있다.

등록된 태그는 다음과 같다.

  • Combo.Active
  • Combo.Activate
  • Combo.InputWindow
  • Combo.CanTransition
  • Combo.End

여기에 더해 시커와 드라카르용 Combo 이벤트 태그도 있다.

  • Event.Skill.Seeker.Combo.Hit
  • Event.Skill.Seeker.Combo.LastHit
  • Event.Skill.Drakhar.Combo.Hit
  • Event.Skill.Drakhar.Combo.LastHit

ASC에는 TryActivateComboAbility()도 있다. 이 함수는 ComboIndex를 GameplayEventData.EventMagnitude에 담아 Combo.Activate 이벤트를 보내고, 이벤트 활성화가 안 되면 TryActivateAbilityByClass()로 폴백한다.

이건 꽤 의미 있는 골격이다.

 

왜냐하면 Combo를 단순한 입력 연타가 아니라 이벤트 기반으로 단계 전환 가능한 Ability 시스템으로 만들 준비가 되어 있다는 뜻이기 때문이다.

그래서 현재 프로젝트 기준으로 Combo를 설명할 때는 이렇게 쓰는 편이 정확하다.

Combo는 GAS 태그와 GameplayEvent 기반으로 확장할 수 있는 구조가 들어와 있으며,
현재 구현의 중심은 태그/이벤트 골격 쪽이다.


회복은 Notify보다 AttributeSet 쪽이 더 분명하다

현재 코드에서 힐 쪽은 연출보다 데이터 경로가 더 선명하다.

태그 레지스트리에는 다음 항목이 이미 있다.

  • Ability.Skill.Heal
  • Effect.Heal
  • Data.Heal.Amount
  • GameplayCue.Heal

그리고 UGS_VitalAttributeSet에는 IncomingHeal 메타 어트리뷰트가 있다.

이 값은 PostGameplayEffectExecute()에서 소비되며, 최종적으로 HP를 증가시키고 범위를 보정한다.

흐름만 보면 이렇다.

Heal GameplayEffect 적용
    -> IncomingHeal 변경
    -> VitalAttributeSet::PostGameplayEffectExecute()
    -> HP 증가 및 클램프

즉 현재 프로젝트에서 회복 핵심은 "어느 Notify 프레임에서 회복하느냐"보다

힐 이펙트가 들어오면 AttributeSet이 어떻게 반영하느냐다.


사망도 현재는 AttributeSet -> PlayerState 흐름이 중심이다

사망 역시 지금 C++에서 가장 분명하게 보이는 경로는 다음이다.

Damage 적용
    -> IncomingDamage 반영
    -> VitalAttributeSet에서 HP 감소
    -> HP <= 0 이면 OnOutOfHealth 브로드캐스트
    -> AGS_PlayerState::HandleOutOfHealth()
    -> bIsAlive = false

여기서 중요한 점은 사망 처리 중심이 UGS_VitalAttributeSet과 AGS_PlayerState라는 것이다.


Motion Matching과 전투의 접점은 아직 느슨하다

지금 프로젝트 기준으로는 Motion Matching과 전투의 관계를 이렇게 정리한다.

  1. 이동 표현의 기반은 Motion Matching 자산 쪽에 있다.
  2. 전투 결정의 기반은 GAS 태그, 어빌리티, 이펙트 쪽에 있다.
  3. 두 계층의 연결은 분명히 존재하지만, 현재 코드는 양쪽 기반을 각각 준비해 둔 상태다.

Montage와 Notify는 어디에 남아 있는가

Montage와 Notify가 완전히 사라진 것은 아니다. 다만 현재는 Notify가 전투 판정보다 보조 역할에 더 가깝다.

예를 들면

  • BP_NotifyState_EarlyTransition
  • BP_NotifyState_MontageBlendOut
  • 여러 BP_AnimNotify_FoleyEvent_*

이런 자산 구성은 현재 애니메이션 계층이 최소한 다음 역할은 맡고 있음을 보여 준다.

  • 블렌드 아웃 타이밍 보조
  • 전이 시점 조정
  • 폴리 사운드 트리거

전투 애니메이션 레이어는 여전히 필요하지만,
현재 코드에서 게임플레이를 최종 결정하는 쪽은 Notify보다 Ability와 Effect 쪽이다.


이 구조가 주는 장점

이 접근의 장점은 명확하다.

 

1. 멀티플레이어에서 책임이 선명하다

Ability가 ServerOnly로 동작하므로, 전투 판정과 상태 부여는 서버 기준으로 정리된다. 나중에 연출을 추가하더라도 중심축이 흔들리지 않는다.

 

2. 태그와 이펙트가 재사용 가능하다

롤링 무적, 에임 모드, 힐, 버프, 디버프, 콤보 전환 준비 같은 개념을 모두 GameplayTag와 GameplayEffect로 통일할 수 있다.

 

3. Combo 확장 여지가 이미 있다

현재 Combo는 완성형은 아니지만, 이벤트 기반 확장 골격이 먼저 들어와 있다. 이건 나중에 Montage 섹션, 입력 버퍼링, Notify 기반 전이를 얹기 좋은 구조다.

 

4. Motion Matching과의 충돌을 늦게 푼다

전투 표현을 처음부터 AnimGraph와 Notify에 과하게 밀어 넣지 않으면, locomotion 계층과 전투 계층의 경계를 관리하기가 쉬워진다.

'Dev. > UE 언리얼 엔진' 카테고리의 다른 글

UE5 Motion Matching 5편 :: 다른 프로젝트에 이 시스템을 옮기는 방법  (0) 2026.03.15
UE5 Motion Matching 4편 :: Strafe 전환에서 만난 문제들과 해결 과정  (0) 2026.03.15
UE5 Motion Matching 2편 :: Offset Root Bone, Warping, IK, Aim Offset  (1) 2026.03.13
UE5 Motion Matching 1편 :: 모든 캐릭터가 이동 시스템을 공유하는 구조  (2) 2026.03.12
[GAS] Aim Offset 트러블슈팅... 고개 하나 돌리는 데 4개의 버그를 만났다  (0) 2026.02.12
'Dev./UE 언리얼 엔진' 카테고리의 다른 글
  • UE5 Motion Matching 5편 :: 다른 프로젝트에 이 시스템을 옮기는 방법
  • UE5 Motion Matching 4편 :: Strafe 전환에서 만난 문제들과 해결 과정
  • UE5 Motion Matching 2편 :: Offset Root Bone, Warping, IK, Aim Offset
  • UE5 Motion Matching 1편 :: 모든 캐릭터가 이동 시스템을 공유하는 구조
raindrovvv
raindrovvv
raindrovvv 님의 블로그 입니다.
  • raindrovvv
    raindrovvv 님의 블로그
    raindrovvv
  • 전체
    오늘
    어제
    • 분류 전체보기 (170) N
      • Dev. (163) N
        • AI 인공지능 (27)
        • UE 언리얼 엔진 (81) N
        • Unity 유니티 (0)
        • Wwise 와이즈 (7)
        • 게임 네트워크 (8)
        • 그래픽스 Graphics (22)
        • 프로젝트 (8)
        • 기타 개발 관련 (10)
      • Computer Science (0)
        • 하드웨어 HW (0)
        • 소프트웨어 SW (0)
        • 통신 (0)
        • 데이터 (0)
      • 블로그 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    그래픽스
    TA
    인디게임
    에이전트
    바이브코딩
    트러블슈팅
    Wwise
    깃
    dev
    UE
    언리얼
    Git
    unrealengine
    네트워크
    Unreal
    생산성
    언리얼엔진
    devlog
    AI
    게임개발
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
raindrovvv
UE5 Motion Matching 3편 :: 전투 애니메이션... 그리고 GAS 연동
상단으로

티스토리툴바