• EndMatch(): AliveHiderCount 기반 승패 판정, 전체 플레이어 이동 잠금, GameOver 전환
  • GameState에 EMatchWinner 승자 필드 추가
  • ResolveCapture에 하이더 개인 사망 기록(PlayerState->bIsAlive) 반영
  • 게임오버 이동 잠금이 클라이언트에 안 먹히던 버그 발견 및 수정

 

술래가 다 잡으면 술래 승, 300초 버티면 하이더 승

  1. ResolveCapture에서 AliveHiderCount <= 0이 됐을 때 (전멸 → 술래 승)
  2. StartInGame이 걸어둔 300초 타이머 만료 (시간 종료 → 하이더 승)
FDGameState->Winner = (FDGameState->AliveHiderCount <= 0)
	? EMatchWinner::Tagger
	: EMatchWinner::Hider;

 

Winner는 GameState에 둠 (모든 클라이언트가 봐야 할 값)

 

EndMatch 구현

void AFDGameMode::EndMatch() // 게임 끝
{
    AFDGameState* FDGameState = GetGameState<AFDGameState>();
    if (!FDGameState) return;

    // AliveHiderCount로 승패 판별
    // 0이면 술래 승, 0보다 크면 시간 종료(하이더 승)
    FDGameState->Winner = (FDGameState->AliveHiderCount <= 0)
       ? EMatchWinner::Tagger 
       : EMatchWinner::Hider;

    FDGameState->CurrentPhase = EMatchPhase::GameOver;
    
    // 게임 끝났으니 모든 플레이어 이동 잠금 (카메라는 허용)
    for (APlayerState* PS : GameState->PlayerArray)
    {
       if (AFDPlayerController* FDPC = Cast<AFDPlayerController>(PS->GetOwningController()))
       {
          FDPC->Client_LockMovement();   // RPC로
       }
    }

    GetWorldTimerManager().ClearTimer(PhaseTimerHandle);

    UE_LOG(LogTemp, Warning, TEXT("[GameMode] 게임 종료 - 승자: %s"),
       FDGameState->Winner == EMatchWinner::Tagger ? TEXT("Tagger") : TEXT("Hider"));
}

 

처음 짠 EndMatch()는 CurrentPhase가 GameOver로 바뀌었을 때 못움직이게 하기 위해서 이미 구현되어있던 (팀원이 구현한) LockMovementForScouting을 사용했는데  

for (APlayerState* PS : GameState->PlayerArray)
{
	if (AFDPlayerController* FDPC = Cast<AFDPlayerController>(PS->GetOwningController()))
	{
		FDPC->LockMovementForScouting();  // 처음엔 이렇게 재사용
	}
}

 

 

LaunchSeparateServer로 실제 여러 프로세스 환경에서 테스트해보니 이동 잠금이 안 먹힘

 

LockMovementForScouting()을 확인해보니 서버가 들고 있는 PlayerController 인스턴스에다 SetIgnoreMoveInput(true)를 호출하는 방식이었음 

그래서 서버가 아닌 클라이언트들한테는 전달이 안됐던 것

 

수정

// FDPlayerController.h
UFUNCTION(Client, Reliable)
void Client_LockMovement();

UFUNCTION(Client, Reliable)
void Client_UnlockMovement();
// FDPlayerController.cpp
void AFDPlayerController::Client_LockMovement_Implementation()
{
	SetIgnoreMoveInput(true);
}

void AFDPlayerController::Client_UnlockMovement_Implementation()
{
	SetIgnoreMoveInput(false);
}

 

EndMatch() 호출부도 교체

FDPC->Client_LockMovement();  // 서버 로컬 호출 대신 RPC로

 

기존에 안 쓰이던 LockMovementForScouting()/UnlockMovement()는 확인 후 삭제함

'프로젝트 > Funny Or Die (멀티플레이 술래잡기 게임)' 카테고리의 다른 글

인트로 화면 구성  (0) 2026.07.07
에셋  (0) 2026.07.07
포획/봐주기 팝업 위젯  (0) 2026.07.03
본게임 포획 판정 구현  (0) 2026.07.02
정찰 단계(Scouting) 구현하기  (0) 2026.07.01

+ Recent posts