언리얼엔진5 공부

2025-12-18 TIL: 멀티플레이어 게임 UI 시스템 및 리스폰 로직 구현

Client Side 2025. 12. 18. 21:34

 

1. [UI] 위젯 생명주기 및 메모리 관리 최적화

  • 학습 내용: 게임 내 모든 위젯을 메인 HUD에 미리 배치하고 Collapsed로 숨기는 방식의 문제점 파악.
  • 개선 방안: Victory/Lose 화면처럼 특정 시점에만 필요한 UI는 CreateWidget을 통해 동적으로 생성하여 런타임 메모리 점유율을 낮추는 설계를 학습함.
  • 적용:
    • WBP_InGameWidget: 상시 노출 정보(타이머, 팀 스코어, 개인 상태).
    • WBP_Result: 게임 종료 시 결과에 따라 동적 생성.
    • WBP_Respawning: 사망 시에만 클라이언트 뷰포트에 추가.

2. [C++] 멀티플레이어 팀 스코어 합산 로직 버그 수정

  • 문제 상황: 팀 총합 킬/데스 숫자가 틱마다 기하급수적으로 증가하는 현상 발생.
  • 원인: 델리게이트를 통해 호출되는 합산 함수에서 멤버 변수를 초기화하지 않고 계속 누적(+=)하여 합산했기 때문.
  • 해결: 함수 내부에서 지역 변수(Local Variable)를 사용하여 매 호출 시점의 점수를 0부터 다시 합산하도록 로직을 수정하여 무결성 확보.

3. [Networking] RPC를 이용한 개인 리스폰 시스템

  • 학습 내용: 서버(GameMode)에서 특정 클라이언트의 화면에만 위젯을 띄우기 위한 통신 방식 이해.
  • 구현:
    • Server: HandlePlayerDeath에서 사망자 판정 및 리스폰 타이머 가동.
    • Client RPC: Client_ShowRespawnWidget 함수를 통해 해당 플레이어의 컨트롤러에게만 UI 호출 명령 전달.
    • UI Logic: NativeTick과 DeltaTime을 활용해 서버의 리스폰 지연 시간 동안 ProgressBar 게이지가 실시간으로 줄어드는 연출 구현.
// 매 프레임 남은 시간을 계산하여 Progress Bar와 Text 업데이트
void UAFRespawnWidget::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
    Super::NativeTick(MyGeometry, InDeltaTime);
    ElapsedTime += InDeltaTime;

    // 10초에서 0초로 줄어드는 게이지 및 텍스트 포맷팅
    float NewPercent = FMath::Clamp(1.0f - (ElapsedTime / MaxDuration), 0.0f, 1.0f);
    if (RespawnProgressBar) RespawnProgressBar->SetPercent(NewPercent);

    if (Text_RespawnTime)
    {
        int32 RemainingSeconds = FMath::Max(0, FMath::CeilToInt(MaxDuration - ElapsedTime));
        Text_RespawnTime->SetText(FText::Format(FText::FromString("Please wait {0}s."), RemainingSeconds));
    }
}