diff --git a/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.cpp b/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.cpp index f03d12343f..bd1e1bf0d9 100644 --- a/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.cpp @@ -14,7 +14,7 @@ namespace Multiplayer { - void NetworkTransformComponent::NetworkTransformComponent::Reflect(AZ::ReflectContext* context) + void NetworkTransformComponent::Reflect(AZ::ReflectContext* context) { AZ::SerializeContext* serializeContext = azrtti_cast(context); if (serializeContext) @@ -43,6 +43,11 @@ namespace Multiplayer GetNetBindComponent()->AddEntityPreRenderEventHandler(m_entityPreRenderEventHandler); GetNetBindComponent()->AddEntityCorrectionEventHandler(m_entityCorrectionEventHandler); ParentEntityIdAddEvent(m_parentChangedEventHandler); + + if (!HasController()) + { + OnParentChanged(GetParentEntityId()); + } } void NetworkTransformComponent::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) @@ -123,17 +128,20 @@ namespace Multiplayer void NetworkTransformComponent::OnParentChanged(NetEntityId parentId) { - const ConstNetworkEntityHandle parentEntityHandle = GetNetworkEntityManager()->GetEntity(parentId); - if (parentEntityHandle.Exists()) + if (AZ::TransformInterface* transformComponent = GetEntity()->GetTransform()) { - if (const AZ::Entity* parentEntity = parentEntityHandle.GetEntity()) + const ConstNetworkEntityHandle parentEntityHandle = GetNetworkEntityManager()->GetEntity(parentId); + if (parentEntityHandle.Exists()) { - GetEntity()->GetTransform()->SetParent(parentEntity->GetId()); + if (const AZ::Entity* parentEntity = parentEntityHandle.GetEntity()) + { + transformComponent->SetParent(parentEntity->GetId()); + } + } + else + { + transformComponent->SetParent(AZ::EntityId()); } - } - else - { - GetEntity()->GetTransform()->SetParent(AZ::EntityId()); } } diff --git a/Gems/Multiplayer/Code/Tests/NetworkTransformTests.cpp b/Gems/Multiplayer/Code/Tests/NetworkTransformTests.cpp index 7ea7ea6974..94cb94e000 100644 --- a/Gems/Multiplayer/Code/Tests/NetworkTransformTests.cpp +++ b/Gems/Multiplayer/Code/Tests/NetworkTransformTests.cpp @@ -211,9 +211,6 @@ namespace Multiplayer const NetworkEntityHandle rootHandle(root.m_entity.get(), m_networkEntityTracker.get()); root.m_replicator = AZStd::make_unique(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Authority, rootHandle); root.m_replicator->Initialize(rootHandle); - - root.m_entity->Activate(); - child.m_entity->Activate(); } AZStd::unique_ptr m_root; @@ -228,6 +225,9 @@ namespace Multiplayer TEST_F(ClientNetTransformTests, ClientSetsLocalTmWhenParentIsSet) { + m_root->m_entity->Activate(); + m_child->m_entity->Activate(); + SetTranslationOnNetworkTransform(m_root->m_entity, AZ::Vector3::CreateOne()); SetParentIdOnNetworkTransform(m_child->m_entity, NetEntityId{ 1 }); @@ -249,6 +249,9 @@ namespace Multiplayer TEST_F(ClientNetTransformTests, ClientSetsWorldTmWhenParentIsNotSet) { + m_root->m_entity->Activate(); + m_child->m_entity->Activate(); + SetTranslationOnNetworkTransform(m_root->m_entity, AZ::Vector3::CreateOne()); SetTranslationOnNetworkTransform(m_child->m_entity, AZ::Vector3::CreateZero()); @@ -268,6 +271,9 @@ namespace Multiplayer TEST_F(ClientNetTransformTests, ChildFollowsWhenParentMovesOnServer) { + m_root->m_entity->Activate(); + m_child->m_entity->Activate(); + SetTranslationOnNetworkTransform(m_root->m_entity, AZ::Vector3::CreateOne()); SetParentIdOnNetworkTransform(m_child->m_entity, NetEntityId{ 1 }); @@ -290,4 +296,25 @@ namespace Multiplayer AZ::Vector3::CreateZero() ); } + + TEST_F(ClientNetTransformTests, ChildAttachesToParentIfParentIdIsSetBeforeActivation) + { + m_root->m_entity->Activate(); + + SetTranslationOnNetworkTransform(m_root->m_entity, AZ::Vector3::CreateOne()); + + SetParentIdOnNetworkTransform(m_child->m_entity, NetEntityId{ 1 }); + SetTranslationOnNetworkTransform(m_child->m_entity, AZ::Vector3::CreateZero()); + + m_child->m_entity->Activate(); + + AZ::EntityBus::Broadcast(&AZ::EntityBus::Events::OnEntityActivated, m_root->m_entity->GetId()); + + MultiplayerTick(); + + EXPECT_EQ( + m_child->m_entity->FindComponent()->GetParentId(), + AZ::EntityId(1) + ); + } }