Hi. I have a problem with disabling movement of the clients at the start of the game. I want pawns to spawn when a player is loaded and while the match state is “WaitingToStart” they shouldn’t be able to move. I use PostLogin function in my gamemode to spawn pawns. I want to restrict input of players by changing to specific mapping context inside my character class, which allows them only to look with mouse and open pause menu:
void AG_Character::SetKeyboardInput(bool bEnable)
{
if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem =
ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
if (bEnable)
{
Subsystem->RemoveMappingContext(WaitingForGameMappingContext);
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
else
{
Subsystem->RemoveMappingContext(DefaultMappingContext);
Subsystem->AddMappingContext(WaitingForGameMappingContext, 0);
}
}
}
}
Firstly I tried to call this function with PlayerController inside PostLogin function:
void AG_BaseGameMode::PostLogin(APlayerController* NewPlayer)
{
Super::PostLogin(NewPlayer);
RestartPlayer(NewPlayer);
// I know this is a bad line, it's just for a test
Cast<AG_PlayerController>(NewPlayer)->SetKeyboardInput(false);
}
Here is a SetKeyboardInput function in PlayerController. Here I tried to use client RPC to change mapping context on the client side.
void AG_PlayerController::SetKeyboardInput(bool bEnable)
{
if (HasAuthority() && IsLocalController())
{
G_Character = G_Character.IsValid() ? G_Character : Cast<AG_Character>(GetPawn());
if (!G_Character.IsValid()) return;
G_Character->SetKeyboardInput(bEnable);
}
else
{
Client_SetKeyboardInput(bEnable);
}
}
void AG_PlayerController::Client_SetKeyboardInput_Implementation(bool bEnable)
{
if (GetPawn())
{
G_Character = G_Character.IsValid() ? G_Character : Cast<AG_Character>(GetPawn());
if (!G_Character.IsValid()) return;
G_Character->SetKeyboardInput(bEnable);
}
}
Server side player works perfectly, but all clients still can move when they spawn. But if I try to call this same function in HandleMatchHasStarted it works perfectly both on clients and server:
void AG_BaseGameMode::HandleMatchHasStarted()
{
Super::HandleMatchHasStarted();
for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
{
Cast<AG_PlayerController>(Iterator->Get())->SetKeyboardInput(true);
}
}
I don’t really know what to try next. Maybe there is much easier way to do it, but I didn’t find it.