From 5f73061227aacfce39c8bd37486dd2f7e6b873ec Mon Sep 17 00:00:00 2001 From: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com> Date: Tue, 21 Sep 2021 22:19:21 -0400 Subject: [PATCH] Adding client side on-parent-changed logic for Network Transform Component Signed-off-by: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com> --- .../Components/NetworkTransformComponent.h | 4 +++- .../Components/NetworkTransformComponent.cpp | 17 ++++++++++++++++ .../Code/Tests/CommonHierarchySetup.h | 4 ---- Gems/Multiplayer/Code/Tests/MockInterfaces.h | 2 +- .../Code/Tests/ServerHierarchyTests.cpp | 20 ++++++++----------- 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetworkTransformComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetworkTransformComponent.h index d90e7cddfe..35bf6e9f50 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetworkTransformComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetworkTransformComponent.h @@ -31,9 +31,11 @@ namespace Multiplayer private: void OnPreRender(float deltaTime); void OnCorrection(); - + void OnParentChanged(NetEntityId parentId); + EntityPreRenderEvent::Handler m_entityPreRenderEventHandler; EntityCorrectionEvent::Handler m_entityCorrectionEventHandler; + AZ::Event::Handler m_parentChangedEventHandler; Multiplayer::HostFrameId m_targetHostFrameId = HostFrameId(0); }; diff --git a/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.cpp b/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.cpp index 9ef585a0a0..d284f100ff 100644 --- a/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.cpp @@ -28,6 +28,7 @@ namespace Multiplayer NetworkTransformComponent::NetworkTransformComponent() : m_entityPreRenderEventHandler([this](float deltaTime) { OnPreRender(deltaTime); }) , m_entityCorrectionEventHandler([this]() { OnCorrection(); }) + , m_parentChangedEventHandler([this](NetEntityId parentId) { OnParentChanged(parentId); }) { ; } @@ -41,6 +42,7 @@ namespace Multiplayer { GetNetBindComponent()->AddEntityPreRenderEventHandler(m_entityPreRenderEventHandler); GetNetBindComponent()->AddEntityCorrectionEventHandler(m_entityCorrectionEventHandler); + ParentEntityIdAddEvent(m_parentChangedEventHandler); } void NetworkTransformComponent::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) @@ -97,6 +99,21 @@ namespace Multiplayer } } + void NetworkTransformComponent::OnParentChanged(NetEntityId parentId) + { + const ConstNetworkEntityHandle parentEntityHandle = GetNetworkEntityManager()->GetEntity(parentId); + if (parentEntityHandle.Exists()) + { + if (const AZ::Entity* parentEntity = parentEntityHandle.GetEntity()) + { + GetEntity()->GetTransform()->SetParent(parentEntity->GetId()); + } + } + else + { + GetEntity()->GetTransform()->SetParent(AZ::EntityId()); + } + } NetworkTransformComponentController::NetworkTransformComponentController(NetworkTransformComponent& parent) : NetworkTransformComponentControllerBase(parent) diff --git a/Gems/Multiplayer/Code/Tests/CommonHierarchySetup.h b/Gems/Multiplayer/Code/Tests/CommonHierarchySetup.h index 7fc1eef8b7..2deac1aa27 100644 --- a/Gems/Multiplayer/Code/Tests/CommonHierarchySetup.h +++ b/Gems/Multiplayer/Code/Tests/CommonHierarchySetup.h @@ -391,10 +391,6 @@ namespace Multiplayer SetupEntity(child.m_entity, child.m_netId, NetEntityRole::Authority); SetupEntity(childOfChild.m_entity, childOfChild.m_netId, NetEntityRole::Authority); - // we need a parent-id value to be present in NetworkTransformComponent (which is in client mode and doesn't have a controller) - SetParentIdOnNetworkTransform(child.m_entity, root.m_netId); - SetParentIdOnNetworkTransform(childOfChild.m_entity, child.m_netId); - // Create an entity replicator for the child entity const NetworkEntityHandle childOfChildHandle(childOfChild.m_entity.get(), m_networkEntityTracker.get()); childOfChild.m_replicator = AZStd::make_unique(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Client, childOfChildHandle); diff --git a/Gems/Multiplayer/Code/Tests/MockInterfaces.h b/Gems/Multiplayer/Code/Tests/MockInterfaces.h index 375fe2c5ba..6466fbb555 100644 --- a/Gems/Multiplayer/Code/Tests/MockInterfaces.h +++ b/Gems/Multiplayer/Code/Tests/MockInterfaces.h @@ -101,7 +101,7 @@ namespace UnitTest MOCK_CONST_METHOD0(GetHostTimeMs, AZ::TimeMs()); MOCK_CONST_METHOD0(GetRewindingConnectionId, AzNetworking::ConnectionId()); MOCK_CONST_METHOD1(GetHostFrameIdForRewindingConnection, Multiplayer::HostFrameId(AzNetworking::ConnectionId)); - MOCK_METHOD3(AlterTime, void(Multiplayer::HostFrameId, AZ::TimeMs, AzNetworking::ConnectionId)); + MOCK_METHOD4(AlterTime, void (Multiplayer::HostFrameId, AZ::TimeMs, float, AzNetworking::ConnectionId)); MOCK_METHOD1(SyncEntitiesToRewindState, void(const AZ::Aabb&)); MOCK_METHOD0(ClearRewoundEntities, void()); }; diff --git a/Gems/Multiplayer/Code/Tests/ServerHierarchyTests.cpp b/Gems/Multiplayer/Code/Tests/ServerHierarchyTests.cpp index c262782006..70859909b3 100644 --- a/Gems/Multiplayer/Code/Tests/ServerHierarchyTests.cpp +++ b/Gems/Multiplayer/Code/Tests/ServerHierarchyTests.cpp @@ -109,7 +109,7 @@ namespace Multiplayer TEST_F(ServerSimpleHierarchyTests, Child_Has_Root_Cleared_On_Detach) { - // now detach the child + // now detach the child m_child->m_entity->FindComponent()->SetParent(AZ::EntityId()); EXPECT_EQ( @@ -165,7 +165,7 @@ namespace Multiplayer m_root->m_entity->FindComponent()->IsHierarchyEnabled(), true ); - + StopEntity(m_root->m_entity); m_root->m_entity->Deactivate(); @@ -183,7 +183,7 @@ namespace Multiplayer m_child->m_entity->FindComponent()->IsHierarchyEnabled(), true ); - + StopEntity(m_child->m_entity); m_child->m_entity->Deactivate(); @@ -435,6 +435,9 @@ namespace Multiplayer CreateBranchedHierarchy(*m_root, *m_child, *m_childOfChild, *m_child2, *m_childOfChild2, *m_child2OfChild2); + m_child2->m_entity->FindComponent()->SetParent(m_root->m_entity->GetId()); + m_childOfChild2->m_entity->FindComponent()->SetParent(m_child2->m_entity->GetId()); + m_child2OfChild2->m_entity->FindComponent()->SetParent(m_child2->m_entity->GetId()); m_child->m_entity->FindComponent()->SetParent(m_root->m_entity->GetId()); m_childOfChild->m_entity->FindComponent()->SetParent(m_child->m_entity->GetId()); // now the entities are under one hierarchy @@ -470,13 +473,6 @@ namespace Multiplayer SetupEntity(childOfChild2.m_entity, childOfChild2.m_netId, NetEntityRole::Authority); SetupEntity(child2OfChild2.m_entity, child2OfChild2.m_netId, NetEntityRole::Authority); - // we need a parent-id value to be present in NetworkTransformComponent (which is in client mode and doesn't have a controller) - SetParentIdOnNetworkTransform(child.m_entity, root.m_netId); - SetParentIdOnNetworkTransform(childOfChild.m_entity, child.m_netId); - SetParentIdOnNetworkTransform(child2.m_entity, root.m_netId); - SetParentIdOnNetworkTransform(childOfChild2.m_entity, child2.m_netId); - SetParentIdOnNetworkTransform(child2OfChild2.m_entity, child2.m_netId); - // Create entity replicators const NetworkEntityHandle childOfChild2Handle(childOfChild2.m_entity.get(), m_networkEntityTracker.get()); childOfChild.m_replicator = AZStd::make_unique(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Client, childOfChild2Handle); @@ -1014,8 +1010,8 @@ namespace Multiplayer CreateDeepHierarchy(*m_root, *m_child, *m_childOfChild); - m_root->m_entity->FindComponent()->SetParent(m_root->m_entity->GetId()); - m_childOfChild->m_entity->FindComponent()->SetParent(m_root->m_entity->GetId()); + m_child->m_entity->FindComponent()->SetParent(m_root->m_entity->GetId()); + m_childOfChild->m_entity->FindComponent()->SetParent(m_child->m_entity->GetId()); // now the entities are under one hierarchy }