내일배움캠프_Unreal/TIL

내일배움캠프_Unreal/TIL - Day 124 (260528)

하임 2026. 5. 28. 21:08

사망 파이프라인

1. 엄격한 단방향 책임 분리 (Decoupling)

기존의 스파게티 코드를 방지하기 위해 Lyra 아키텍처의 정석대로 아키텍처 계층 간의 책임을 날카롭게 쪼갬.

  • AttributeSet (Detect): 체력을 감쇠하고 0.0f로 안전하게 클램프한 뒤, Old > 0 && New == 0인 정확한 사망 트랜지션 시점에 단일 네이티브 델리게이트로 신호만 보냄.
  • HealthComponent (Orchestrate): 신호를 받아 중복 처리를 막고, 기존 능력을 정리한 뒤 사망 어빌리티(GA_Die)를 강제로 발화하는 중앙 통제실 역할을 수행.
  • Character (Broadcast): 진영에 맞는 고유 Dead 태그를 인스턴스에 박고, 전역 메시지 서브시스템으로 페이로드를 실어 전파함.

2. 다중 발화 방지를 위한 Latch 패턴의 중요성

  • 문제 상황: 같은 프레임에 다중 연타(오버킬)가 들어오거나, 네트워크 복제(Replication) 과정에서 속성 변경 데이터가 재전송될 경우 사망 처리가 2번 이상 실행되어 UI가 겹치거나 전리품 드롭이 더블 카운팅되는 치명적인 버그 리스크가 존재했음.
  • 해결책: URetrieveHealthComponent 내부에 bDeathStarted라는 불리언 래치(Latch) 변수를 두어, 첫 진입 시 즉시 true로 잠그고 이후의 모든 사망 진입 시도는 early return 시키는 안전장치를 확보함.

3. GAS 어빌리티 취소 면역(Immunity) 함정 해결

  • 논리적 모순 발생: 캐릭터가 죽으면 활성 중인 모든 능력(콤보, 대시 등)을 CancelAllAbilities로 날려야 함. 하지만 무턱대고 전체 취소를 때리면 연출을 담당하는 GA_Die 본인마저 취소되어 시체가 모션 없이 굳어버리는 버그가 발생함.
  • 화이트리스트 솔루션: GA_Die에 Ability_Common_Die 태그를 배정하고, 캔슬 호출 시 면역 컨테이너(ImmuneTags)에 이를 담아 통과시키는 방식으로 해결함.
  • 자가 차단 방지: 또한, GA_Die 내부의 ActivationBlockedTags에 State_Player_Dead가 포함되어 있으면 태그가 박히는 타이밍 꼬임으로 어빌리티가 자가 차단되는 대형 함정이 있으므로, 사망 어빌리티만큼은 차단 태그에서Dead 태그를 제외해야 한다는 예외 설계의 중요성을 배움.

4. 객체지향 분업 및 가해자 데이터 모델링

  • 베이스와 파생의 경계: 베이스 캐릭터(ARetrieveCombatCharacter)는 물리 엔진 정지 등 공통 본연의 기능만 수행하고, 플레이어(ASovereignCharacter)와 적 캐릭터는 각각 다른 전용 페이로드(FPlayerDiedPayload vs FMonsterDiedPayload)를 조립하여 서버 측에서 딱 1회 발행하도록 오버라이딩 분업을 깔끔하게 정리함.
  • 시그니처 유지와 캐싱: OnDeathStarted 델리게이트 인자를 확장하면 BP 호환성이 깨지므로, 데미지 컨텍스트에서 추출한 Killer (책임 주체 Controller/Pawn)와 DamageCauser (직접적인 타격 도구/투사체) 데이터를 컴포넌트 멤버 변수에 임시 캐싱하여 하위 진영 클래스가 꺼내 쓰게 만들도록 설계함.