언리얼엔진5 공부

TIL: Unreal Engine 5 멀티플레이 킬 로그 시스템 구현

Client Side 2025. 12. 24. 16:03

1. 개요

  • 목표: 플레이어 처치 시 우측 상단에 킬 로그를 3초간 표시하고, 애니메이션 연출(슬라이드+페이드) 적용.
  • 핵심 기술: C++ RPC (Client), WBP Animation, Widget Interaction, Vertical Box 최적화.

2. UI 구조 (Hierarchy)

  • WBP_KillLogContainer: 화면에 고정된 바구니. Vertical Box를 사용하여 로그를 순차적으로 쌓음.
  • WBP_KillLogEntry: 개별 로그 조각. 텍스트(Killer, Victim)와 아이콘으로 구성.

3. 주요 구현 내용

A. C++ 기반 UI 제어 (BindWidgetAnim)

  • meta = (BindWidgetAnim)을 사용해 블루프린트에서 만든 애니메이션을 C++에서 직접 제어.
  • NativeConstruct에서 애니메이션을 재생(PlayAnimation)하고, 타이머를 통해 자동 삭제 로직 구현.
  • 학습 포인트: std::vector 대신 언리얼 전용 컨테이너인 TArray를 사용하고, TimerManager를 활용해 Tick 사용을 최소화함.

B. 멀티플레이어 동기화 (RPC)

  • 흐름: GameMode(서버) -> 모든 PlayerController(클라이언트) -> KillLogContainer(로컬 UI).
  • Client 매크로와 Reliable 옵션을 사용하여 네트워크 상에서 유실 없이 모든 클라이언트의 화면에 로그가 뜨도록 구현.

C. 렌더링 최적화

  • 슬라이드 연출 시 Layout 수치 대신 Render Transform (Translation)을 수정하여 재계산(Re-layout) 비용을 절감.

4. 핵심 코드 요약 (Netmarble 실무 스타일)

// 1. 서버에서 모든 클라이언트에게 전파 (GameMode)
for (FConstPlayerControllerIterator It = GetWorld()->GetPlayerControllerIterator(); It; ++It)
{
    if (AAFPlayerController* PC = Cast<AAFPlayerController>(It->Get()))
    {
        PC->Client_ShowKillLog(KillerName, KillerColor, VictimName, VictimColor);
    }
}

// 2. 클라이언트 UI 추가 및 3초 뒤 자동 삭제 (Entry)
void UAFKillLogEntry::NativeConstruct()
{
    Super::NativeConstruct();
    PlayAnimation(AppearAnim); // "샥!" 하고 나타나는 연출

    // 3초 후 삭제 예약 (효율적인 메모리 관리)
    GetWorld()->GetTimerManager().SetTimer(DestroyTimerHandle, this, &UAFKillLogEntry::RemoveSelf, 3.0f, false);
}

 

5. QnA

 

  • Q: 킬 로그를 GameState가 아닌 Controller에서 처리한 이유는?
    • A: UI 생성 권한은 각 클라이언트의 로컬 컨트롤러에 있기 때문입니다. 서버 전용 클래스인 GameMode에서 발생한 이벤트를 각 클라이언트의 화면으로 전달하기 위해 PlayerController의 RPC를 활용했습니다.
  • Q: 로그가 너무 많이 쌓이면 어떻게 처리하나?
    • A: Vertical Box의 자식 개수를 체크하여 일정 수(예: 5개)가 넘어가면 가장 오래된 로그(RemoveChildAt(0))를 삭제하도록 최적화했습니다.

 

6. 회고

  • 성과: 비전공자로서 어렵게 느껴졌던 C++와 블루프린트 애니메이션의 연동을 성공함.
  • 성장:  '네트워크 최적화'와 '가독성 좋은 UI 로직'에 대해 이해함.