- EndMatch(): AliveHiderCount 기반 승패 판정, 전체 플레이어 이동 잠금, GameOver 전환
- GameState에 EMatchWinner 승자 필드 추가
- ResolveCapture에 하이더 개인 사망 기록(PlayerState->bIsAlive) 반영
- 게임오버 이동 잠금이 클라이언트에 안 먹히던 버그 발견 및 수정
술래가 다 잡으면 술래 승, 300초 버티면 하이더 승
- ResolveCapture에서 AliveHiderCount <= 0이 됐을 때 (전멸 → 술래 승)
- 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 |
