Skip to content
This repository has been archived by the owner on Aug 29, 2024. It is now read-only.

Fix initial player control in a multi-worker (zoned) deployment. #1359

Merged
merged 2 commits into from
Sep 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- When schema compiler fails, schema generation correctly shows an error.
- Fixed crash during initialization when running GenerateSchemaCommandlet.
- Generating schema after deleting the schema database but not the generated schema folder will now correctly trigger an initial schema generation.
- Fixed an issue that would prevent player movement in a zoned deployment.

## [`0.6.1`] - 2019-08-15

### Features:
- The [Multiserver zoning shooter tutorial](https://docs.improbable.io/unreal/alpha/content/tutorials/multiserver-shooter/tutorial-multiserver-intro) has been updated to use the Example Project.

### Bug fixes:
### Bug fixes:
- Simulated player launch configurations are no longer invalid when the GDK is installed as an Engine Plugin.
- RPCs that have been queued for execution for more than 1 second (the default value in `SpatialGDKSettings QueuedIncomingRPCWaitTime`) are now executed even if there are unresolved parameters. This stops unresolved parameters from blocking the execution queue.
- Offloading is no longer enabled by default in the Example Project. You can toggle offloading on using [these steps](https://docs.improbable.io/unreal/alpha/content/tutorials/offloading-tutorial/offloading-setup#step-4-enable-offloading).
Expand Down
19 changes: 19 additions & 0 deletions SpatialGDK/Source/SpatialGDK/Private/Interop/SpatialReceiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Engine/Engine.h"
#include "Engine/World.h"
#include "GameFramework/PlayerController.h"
#include "GameFramework/PlayerState.h"
#include "Kismet/GameplayStatics.h"
#include "TimerManager.h"

Expand Down Expand Up @@ -313,6 +314,11 @@ void USpatialReceiver::HandleActorAuthority(const Worker_AuthorityChangeOp& Op)

// If we became authoritative over the position component. set our role to be ROLE_Authority
// and set our RemoteRole to be ROLE_AutonomousProxy if the actor has an owning connection.
// Note: Pawn, PlayerController, and PlayerState for player-owned characters can arrive in
// any order on non-authoritative servers, so it's possible that we don't yet know if a pawn
// is player controlled when gaining authority over the pawn and need to wait for the player
// state. Likewise, it's possible that the player state doesn't have a pointer to its pawn
// yet, so we need to wait for the pawn to arrive.
if (Op.component_id == SpatialConstants::POSITION_COMPONENT_ID)
{
if (Op.authority == WORKER_AUTHORITY_AUTHORITATIVE)
Expand All @@ -328,11 +334,24 @@ void USpatialReceiver::HandleActorAuthority(const Worker_AuthorityChangeOp& Op)
}
else if (APawn* Pawn = Cast<APawn>(Actor))
{
// The following check will return false on non-authoritative servers if the PlayerState hasn't been received yet.
if (Pawn->IsPlayerControlled())
{
Pawn->RemoteRole = ROLE_AutonomousProxy;
}
}
else if (const APlayerState* PlayerState = Cast<APlayerState>(Actor))
{
// The following check will return false on non-authoritative servers if the Pawn hasn't been received yet.
if (APawn* PawnFromPlayerState = PlayerState->GetPawn())
{
check(PlayerState->bIsABot || PawnFromPlayerState->IsPlayerControlled());
if (PawnFromPlayerState->IsPlayerControlled())
{
PawnFromPlayerState->RemoteRole = ROLE_AutonomousProxy;
}
}
}

UpdateShadowData(Op.entity_id);

Expand Down