접속한 플레이어들 중 한 명을 랜덤으로 술래로, 나머지를 숨는자로 배정하고 그 역할에 맞는 캐릭터로 정확히 스폰해야함
팀원이 Tagger와 Hider 캐릭터를 구현해둔 상태라 PIE를 돌려봤는데 의도한 Tagger/Hider 캐릭터가 아니라 엔진 기본 DefaultPawn이 스폰됨 (GameMode를 만들어둔 걸로 설정해두지 않았을 뿐더러 PostLogin, AssignRoles 둘 다 구현 전이라 역할을 정해주는 로직 자체가 없었기 때문이라서 당연함)
구현 방향
PostLogin 시점에는 아직 누가 술래인지 모르므로 역할이 정해지기 전엔 아무 캐릭터도 스폰하지 않도록 막아두고(기본으로 DefaultPawn을 설정하니까 그걸 nullptr로 막음)
AssignRoles에서 역할이 확정된 후에 그 역할에 맞는 캐릭터로 다시 스폰을 요청함
- GameMode 생성자: PlayerStateClass를 AFDPlayerState로 지정 DefaultPawnClass는 nullptr로 비워서 역할 미배정 상태에서는 스폰이 일어나지 않게 함
- GetDefaultPawnClassForController_Implementation 오버라이드: 컨트롤러에게 어떤 Pawn을 줄지 정하는 곳
PlayerState.RoleTag를 보고 TaggerClass/HiderClass 중 하나를 리턴하도록 분기
RoleTag가 아직 None이면 Super 호출 -> DefaultPawnClass(nullptr) 리턴 - AssignRoles(): GameState->PlayerArray에서 현재 접속자 전체를 가져와 랜덤으로 한 명을 Tagger로, 나머지를 Hider로 RoleTag 설정
- 모든 RoleTag 설정이 끝난 뒤에 한꺼번에 RestartPlayer를 호출해 재스폰
UClass* AFDGameMode::GetDefaultPawnClassForController_Implementation(AController* InController)
{
if (const AFDPlayerState* FDPS = InController ? InController->GetPlayerState<AFDPlayerState>() : nullptr)
{
if (FDPS->RoleTag == EFDRole::Tagger && TaggerClass) return TaggerClass;
if (FDPS->RoleTag == EFDRole::Hider && HiderClass) return HiderClass;
}
return Super::GetDefaultPawnClassForController_Implementation(InController);
}
void AFDGameMode::AssignRoles()
{
TArray<APlayerState*> Players = GameState->PlayerArray;
if (Players.Num() == 0) return;
const int32 TaggerIndex = FMath::RandRange(0, Players.Num() - 1);
// 1단계: RoleTag 전부 먼저 확정
for (int32 i = 0; i < Players.Num(); ++i)
{
AFDPlayerState* FDPS = Cast<AFDPlayerState>(Players[i]);
if (!FDPS) continue;
FDPS->RoleTag = (i == TaggerIndex) ? EFDRole::Tagger : EFDRole::Hider;
}
// 2단계: 확정된 뒤 한꺼번에 재스폰 요청
for (APlayerState* PS : Players)
{
if (AController* Controller = PS->GetOwningController())
{
RestartPlayer(Controller);
}
}
}
트러블슈팅: RoleTag 복제(OnRep)가 한 명당 2번씩 호출되는 문제
PlayerState.RoleTag에 OnRep 콜백을 달아 클라이언트 복제 확인용 디버그 메시지를 띄웠는데 화면에 같은 값이 한 명당 2번씩 찍히는 현상이 발생

디버깅 과정
OnRep_RoleTag에 중단점을 걸고 디버깅 해봤는데 처음 중단점에 걸렸을 땐 화면에 아무것도 뜨지 않음 -> F5를 한 번 더 누르니까 메시지 2개가 동시에 나타남
원인을 모르겠어서 ReStart 호출될 때 Tag Replication이 한 번 더 되나 싶어서 RoleTag 만들어질 때 디버깅 찍어봤는데 서버에서는 한 번 설정되고 있는 게 맞음

원인을 모르겠어서 튜터님을 찾아뵙고 여쭤보니 PIE 멀티플레이어 테스트 설정에서 "Run Under One Process"가 체크되어 있던 것이 원인이었음
Run Under One Process 설정은 로그가 하나의 화면에 다 찍히는 걸 원할 때 (디버깅할 때) 설정해놓고 하는거지 실제 상황과 같은 상황을 구현할 땐 꺼놓고 해야됨
안 그러면 이 옵션이 켜진 상태에서는 위처럼 중복으로 처리되는 오류가 생길 수 있음
'프로젝트 > Funny Or Die (멀티플레이 술래잡기 게임)' 카테고리의 다른 글
| 정찰 단계(Scouting) 구현하기 (0) | 2026.07.01 |
|---|---|
| Seamless Travel 이후 캐릭터 입력이 먹지 않던 문제 (0) | 2026.07.01 |
| 로비 UI 협업 (0) | 2026.06.30 |
| 레벨별 GameMode 분리와 로비 시스템 구현 (0) | 2026.06.30 |
| 기술 설계 초안 (0) | 2026.06.26 |
