게임 Pollute 는 플레이어가 사람, 몬스터, 관전자 3가지 캐릭터를 사용한다.
컨트롤러는 3가지 캐릭터에 대한 ChangePossess 를 진행해야한다.
구현하면서 배운 것과 놓친 부분들
1. Possess/UnPossess 는 항상 Server 에서 진행한다.
2. 리플리케이트 되어 있는 액터의 생성과 파괴가 서버에서 이루어진다면 동기화된다.
3. 클라에서는 캐릭터 생성하면서 Possess 시 Beginplay에서 컨트롤러를 정상적으로 가져올 수 있지만 Server 에서는 안된다. 안전하게 PossessedBy 함수를 사용한다.
4. 사람이 몬스터로 변한다면 PlayerHUD 를 Off 해야하며 만약 아이템을 들고 있다면 Detach 해야한다.
5. 몬스터로 변했다면 다시 무작위로 남아있는 사람 플레이어에게 저주를 적용해야한다.
캐릭터 변경에 대한 함수는 Controller 에서 관리한다.
ChangeToSpector 는 ServerRPC 이고 ChangeToMonster 는 일반 함수인 이유
만들다보니 ChangeToSpector 는 클라에서 사용하고 ChangeToMonster 는 서버에서 사용하기 때문이다.
팀원들도 자주 사용하는 함수여서 용도에 맞게 바꾸어두었다.
구현 내용
플레이어가 죽었을 때 호출하며 관전자 플레이어가 된다
사람 및 몬스터에서 죽을 경우에 대한 예외처리를 진행한다.
void ALCU_PlayerController::ServerRPC_ChangeToSpector_Implementation()
{
// 현재 Possess 하고 있는 폰 가져오기
APawn* player = GetPawn();
ALCU_PlayerCharacter* PlayerCharacter = Cast<ALCU_PlayerCharacter>(player);
if(PlayerCharacter && HasAuthority())
{
PlayerCharacter->NetMulticast_DetachItem();
}
// 저주를 다시 시작합니다.
if(PlayerCharacter && PlayerCharacter->GetHasCurse())
{
AP_GameState* GS = Cast<AP_GameState>(UGameplayStatics::GetGameState(GetWorld()));
if (GS)
{
GS->RestartCurse();
}
}
ClientRPC_ItemUIOff();
UnPossess();
// Spector Pawn 생성
AGameModeBase* gm = GetWorld()->GetAuthGameMode();
ASpectatorPawn* spector = GetWorld()->SpawnActor<ASpectatorPawn>(gm->SpectatorClass,player->GetActorTransform());
// 생성된 Spector 로 Possess
Possess(spector);
if (IsValid(player))
{
player->Destroy();
}
AP_GameState* GS =Cast<AP_GameState>(UGameplayStatics::GetGameState(GetWorld()));
if (GS)
{
GS->GetAllCharacters();
}
}
void ALCU_PlayerController::ChangeToMonster()
{
if(!IsValid(MonChar)) return;
// 현재 Possess 하고 있는 폰 가져오기
APawn* player = GetPawn();
ALCU_PlayerCharacter* PlayerCharacter = Cast<ALCU_PlayerCharacter>(player);
if(PlayerCharacter && HasAuthority())
{
PlayerCharacter->NetMulticast_DetachItem();
}
ClientRPC_ItemUIOff();
UnPossess();
// Spector Pawn 생성
AGameModeBase* gm = GetWorld()->GetAuthGameMode();
ALCU_MonsterCharacter* MonSter = GetWorld()->SpawnActor<ALCU_MonsterCharacter>(MonChar,player->GetActorTransform());
// 생성된 Spector 로 Possess
Possess(MonSter);
player->Destroy();
// 사람 플레이어가 얼마나 남았는지 확인하고 다시
AP_GameState* GS =Cast<AP_GameState>(UGameplayStatics::GetGameState(GetWorld()));
if (GS)
{
GS->GetAllCharacters();
}
}
'프로젝트 > Pollute' 카테고리의 다른 글
피직스 머터리얼을 이용한 사운드 변경 (0) | 2025.01.03 |
---|---|
플레이어 블렌드 스페이스 변경 & 속도 동기화 - 스테미나 (1) | 2024.12.13 |
저주 및 몬스터 네트워크 동기화 (0) | 2024.12.12 |