diff --git a/SpatialGDK/Source/SpatialGDK/Private/EngineClasses/SpatialActorChannel.cpp b/SpatialGDK/Source/SpatialGDK/Private/EngineClasses/SpatialActorChannel.cpp index 2afa4811ff..8ce47032d7 100644 --- a/SpatialGDK/Source/SpatialGDK/Private/EngineClasses/SpatialActorChannel.cpp +++ b/SpatialGDK/Source/SpatialGDK/Private/EngineClasses/SpatialActorChannel.cpp @@ -73,6 +73,7 @@ USpatialActorChannel::USpatialActorChannel(const FObjectInitializer& ObjectIniti , NetDriver(nullptr) , LastSpatialPosition(FVector::ZeroVector) , bCreatingNewEntity(false) + , bCreatedEntity(false) { } @@ -160,6 +161,15 @@ void USpatialActorChannel::UpdateShadowData() { check(Actor); + // If this channel was responsible for creating the channel, we do not want to initialize our shadow data + // to the latest state since there could have been state that has changed between creation of the entity + // and gaining of authority. Revisit this with UNR-1034 + // TODO: UNR-1029 - log when the shadow data differs from the current state of the Actor. + if (bCreatedEntity) + { + return; + } + // Refresh shadow data when crossing over servers to prevent stale/out-of-date data. ActorReplicator->RepLayout->InitShadowData(ActorReplicator->ChangelistMgr->GetRepChangelistState()->StaticBuffer, Actor->GetClass(), (uint8*)Actor); @@ -714,6 +724,7 @@ void USpatialActorChannel::OnCreateEntityResponse(const Worker_CreateEntityRespo return; } + bCreatedEntity = true; UE_LOG(LogSpatialActorChannel, Verbose, TEXT("Created entity (%lld) for: %s."), Op.entity_id, *Actor->GetName()); } diff --git a/SpatialGDK/Source/SpatialGDK/Private/Interop/SpatialReceiver.cpp b/SpatialGDK/Source/SpatialGDK/Private/Interop/SpatialReceiver.cpp index 55e2af7ee3..5b34b1be93 100644 --- a/SpatialGDK/Source/SpatialGDK/Private/Interop/SpatialReceiver.cpp +++ b/SpatialGDK/Source/SpatialGDK/Private/Interop/SpatialReceiver.cpp @@ -268,6 +268,11 @@ void USpatialReceiver::HandleActorAuthority(Worker_AuthorityChangeOp& Op) } else if (Op.authority == WORKER_AUTHORITY_NOT_AUTHORITATIVE) { + if (USpatialActorChannel* ActorChannel = NetDriver->GetActorChannelByEntityId(Op.entity_id)) + { + ActorChannel->bCreatedEntity = false; + } + Actor->Role = ROLE_SimulatedProxy; Actor->RemoteRole = ROLE_Authority; diff --git a/SpatialGDK/Source/SpatialGDK/Private/Utils/ComponentFactory.cpp b/SpatialGDK/Source/SpatialGDK/Private/Utils/ComponentFactory.cpp index 5c4a66fb37..234a49348b 100644 --- a/SpatialGDK/Source/SpatialGDK/Private/Utils/ComponentFactory.cpp +++ b/SpatialGDK/Source/SpatialGDK/Private/Utils/ComponentFactory.cpp @@ -188,6 +188,7 @@ void ComponentFactory::AddProperty(Schema_Object* Object, Schema_FieldId FieldId FUnrealObjectRef ObjectRef = FUnrealObjectRef::NULL_OBJECT_REF; UObject* ObjectValue = ObjectProperty->GetObjectPropertyValue(Data); + if (ObjectValue != nullptr && !ObjectValue->IsPendingKill()) { FNetworkGUID NetGUID; @@ -204,7 +205,8 @@ void ComponentFactory::AddProperty(Schema_Object* Object, Schema_FieldId FieldId } } - if (NetGUID.IsValid()) + // The secondary part of the check is only necessary until we have bulk reservation of entity ids UNR-673 + if (NetGUID.IsValid() || (ObjectValue->IsSupportedForNetworking() && !ObjectValue->IsFullNameStableForNetworking())) { ObjectRef = PackageMap->GetUnrealObjectRefFromNetGUID(NetGUID); } diff --git a/SpatialGDK/Source/SpatialGDK/Public/EngineClasses/SpatialActorChannel.h b/SpatialGDK/Source/SpatialGDK/Public/EngineClasses/SpatialActorChannel.h index 7b7480f3cb..8d3ed82c22 100644 --- a/SpatialGDK/Source/SpatialGDK/Public/EngineClasses/SpatialActorChannel.h +++ b/SpatialGDK/Source/SpatialGDK/Public/EngineClasses/SpatialActorChannel.h @@ -132,6 +132,9 @@ class SPATIALGDK_API USpatialActorChannel : public UActorChannel void UpdateShadowData(); + // If this actor channel is responsible for creating a new entity, this will be set to true once the entity is created. + bool bCreatedEntity; + protected: // UChannel Interface virtual bool CleanUp(const bool bForDestroy) override; diff --git a/SpatialGDK/Source/SpatialGDK/Public/EngineClasses/SpatialNetDriver.h b/SpatialGDK/Source/SpatialGDK/Public/EngineClasses/SpatialNetDriver.h index ee09032cc7..95ea69989e 100644 --- a/SpatialGDK/Source/SpatialGDK/Public/EngineClasses/SpatialNetDriver.h +++ b/SpatialGDK/Source/SpatialGDK/Public/EngineClasses/SpatialNetDriver.h @@ -163,7 +163,6 @@ class SPATIALGDK_API USpatialNetDriver : public UIpNetDriver TMap EntityToActorChannel; - // Timer manager. FTimerManager* TimerManager; bool bAuthoritativeDestruction;