NetworkTransformTests.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0 OR MIT
  5. *
  6. */
  7. #include <CommonHierarchySetup.h>
  8. #include <MockInterfaces.h>
  9. #include <AzCore/Component/Entity.h>
  10. #include <AzCore/Console/Console.h>
  11. #include <AzCore/Name/Name.h>
  12. #include <AzCore/UnitTest/TestTypes.h>
  13. #include <AzCore/UnitTest/UnitTest.h>
  14. #include <AzFramework/Components/TransformComponent.h>
  15. #include <AzTest/AzTest.h>
  16. #include <Multiplayer/Components/NetBindComponent.h>
  17. #include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.h>
  18. namespace Multiplayer
  19. {
  20. using namespace testing;
  21. using namespace ::UnitTest;
  22. /*
  23. * (Networked) Parent -> (Networked) Child
  24. */
  25. class ServerNetTransformTests : public HierarchyTests
  26. {
  27. public:
  28. void SetUp() override
  29. {
  30. HierarchyTests::SetUp();
  31. m_root = AZStd::make_unique<EntityInfo>(1, "root", NetEntityId{ 1 }, EntityInfo::Role::Root);
  32. m_child = AZStd::make_unique<EntityInfo>(2, "child", NetEntityId{ 2 }, EntityInfo::Role::Child);
  33. CreateNetworkParentChild(*m_root, *m_child);
  34. AZ::Transform rootTransform = AZ::Transform::CreateIdentity();
  35. rootTransform.SetTranslation(AZ::Vector3::CreateOne());
  36. m_root->m_entity->FindComponent<AzFramework::TransformComponent>()->SetWorldTM(rootTransform);
  37. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetWorldTM(rootTransform);
  38. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  39. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetLocalTM(AZ::Transform::CreateIdentity());
  40. AZ::EntityBus::Broadcast(&AZ::EntityBus::Events::OnEntityActivated, m_root->m_entity->GetId());
  41. MultiplayerTick();
  42. }
  43. void TearDown() override
  44. {
  45. m_child.reset();
  46. m_root.reset();
  47. HierarchyTests::TearDown();
  48. }
  49. void PopulateNetworkEntity(const EntityInfo& entityInfo)
  50. {
  51. entityInfo.m_entity->CreateComponent<AzFramework::TransformComponent>();
  52. entityInfo.m_entity->CreateComponent<NetBindComponent>();
  53. entityInfo.m_entity->CreateComponent<NetworkTransformComponent>();
  54. }
  55. void CreateNetworkParentChild(EntityInfo& root, EntityInfo& child)
  56. {
  57. PopulateNetworkEntity(root);
  58. SetupEntity(root.m_entity, root.m_netId, NetEntityRole::Authority);
  59. PopulateNetworkEntity(child);
  60. SetupEntity(child.m_entity, child.m_netId, NetEntityRole::Authority);
  61. // Create an entity replicator for the child entity
  62. const NetworkEntityHandle childHandle(child.m_entity.get(), m_networkEntityTracker.get());
  63. child.m_replicator = AZStd::make_unique<EntityReplicator>(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Client, childHandle);
  64. child.m_replicator->Initialize(childHandle);
  65. // Create an entity replicator for the root entity
  66. const NetworkEntityHandle rootHandle(root.m_entity.get(), m_networkEntityTracker.get());
  67. root.m_replicator = AZStd::make_unique<EntityReplicator>(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Client, rootHandle);
  68. root.m_replicator->Initialize(rootHandle);
  69. root.m_entity->Activate();
  70. child.m_entity->Activate();
  71. }
  72. AZStd::unique_ptr<EntityInfo> m_root;
  73. AZStd::unique_ptr<EntityInfo> m_child;
  74. void MultiplayerTick()
  75. {
  76. m_root->m_entity->FindComponent<NetBindComponent>()->NotifyPreRender(0.1f);
  77. m_child->m_entity->FindComponent<NetBindComponent>()->NotifyPreRender(0.1f);
  78. }
  79. };
  80. TEST_F(ServerNetTransformTests, SanityCheck)
  81. {
  82. EXPECT_EQ(
  83. m_root->m_entity->FindComponent<AzFramework::TransformComponent>()->GetWorldTM().GetTranslation(),
  84. AZ::Vector3::CreateOne()
  85. );
  86. EXPECT_EQ(
  87. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->GetWorldTM().GetTranslation(),
  88. AZ::Vector3::CreateOne()
  89. );
  90. EXPECT_EQ(
  91. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->GetLocalTM().GetTranslation(),
  92. AZ::Vector3::CreateZero()
  93. );
  94. }
  95. TEST_F(ServerNetTransformTests, NetTransformSavesLocalTransformWhenParentSet)
  96. {
  97. EXPECT_EQ(
  98. m_child->m_entity->FindComponent<NetworkTransformComponent>()->GetTranslation(),
  99. AZ::Vector3::CreateZero()
  100. );
  101. }
  102. TEST_F(ServerNetTransformTests, NetTransformSavesWorldTransformWhenParentIsNotSet)
  103. {
  104. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  105. MultiplayerTick();
  106. EXPECT_EQ(
  107. m_child->m_entity->FindComponent<NetworkTransformComponent>()->GetTranslation(),
  108. AZ::Vector3::CreateOne() // back at the parent translation
  109. );
  110. }
  111. TEST_F(ServerNetTransformTests, ParentMovesChildNetTransformDoesntChange)
  112. {
  113. EXPECT_EQ(
  114. m_child->m_entity->FindComponent<NetworkTransformComponent>()->GetTranslation(),
  115. AZ::Vector3::CreateZero()
  116. );
  117. // move the parent
  118. AZ::Transform rootTransform = AZ::Transform::CreateIdentity();
  119. rootTransform.SetTranslation(AZ::Vector3::CreateOne() * 10.f);
  120. m_root->m_entity->FindComponent<AzFramework::TransformComponent>()->SetWorldTM(rootTransform);
  121. MultiplayerTick();
  122. EXPECT_EQ(
  123. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->GetWorldTM().GetTranslation(),
  124. AZ::Vector3::CreateOne() * 10.f
  125. );
  126. // child local tm doesn't change
  127. EXPECT_EQ(
  128. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->GetLocalTM().GetTranslation(),
  129. AZ::Vector3::CreateZero()
  130. );
  131. EXPECT_EQ(
  132. m_child->m_entity->FindComponent<NetworkTransformComponent>()->GetTranslation(),
  133. AZ::Vector3::CreateZero()
  134. );
  135. }
  136. /*
  137. * (Networked) Parent -> (Networked) Child
  138. */
  139. class ClientNetTransformTests : public HierarchyTests
  140. {
  141. public:
  142. void SetUp() override
  143. {
  144. HierarchyTests::SetUp();
  145. m_root = AZStd::make_unique<EntityInfo>(1, "root", NetEntityId{ 1 }, EntityInfo::Role::Root);
  146. m_child = AZStd::make_unique<EntityInfo>(2, "child", NetEntityId{ 2 }, EntityInfo::Role::Child);
  147. CreateNetworkParentChild(*m_root, *m_child);
  148. }
  149. void TearDown() override
  150. {
  151. m_child.reset();
  152. m_root.reset();
  153. HierarchyTests::TearDown();
  154. }
  155. void PopulateNetworkEntity(const EntityInfo& entityInfo)
  156. {
  157. entityInfo.m_entity->CreateComponent<AzFramework::TransformComponent>();
  158. entityInfo.m_entity->CreateComponent<NetBindComponent>();
  159. entityInfo.m_entity->CreateComponent<NetworkTransformComponent>();
  160. }
  161. void CreateNetworkParentChild(EntityInfo& root, EntityInfo& child)
  162. {
  163. PopulateNetworkEntity(root);
  164. SetupEntity(root.m_entity, root.m_netId, NetEntityRole::Client);
  165. PopulateNetworkEntity(child);
  166. SetupEntity(child.m_entity, child.m_netId, NetEntityRole::Client);
  167. // Create an entity replicator for the child entity
  168. const NetworkEntityHandle childHandle(child.m_entity.get(), m_networkEntityTracker.get());
  169. child.m_replicator = AZStd::make_unique<EntityReplicator>(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Authority, childHandle);
  170. child.m_replicator->Initialize(childHandle);
  171. // Create an entity replicator for the root entity
  172. const NetworkEntityHandle rootHandle(root.m_entity.get(), m_networkEntityTracker.get());
  173. root.m_replicator = AZStd::make_unique<EntityReplicator>(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Authority, rootHandle);
  174. root.m_replicator->Initialize(rootHandle);
  175. }
  176. AZStd::unique_ptr<EntityInfo> m_root;
  177. AZStd::unique_ptr<EntityInfo> m_child;
  178. void MultiplayerTick()
  179. {
  180. m_root->m_entity->FindComponent<NetBindComponent>()->NotifyPreRender(0.1f);
  181. m_child->m_entity->FindComponent<NetBindComponent>()->NotifyPreRender(0.1f);
  182. }
  183. };
  184. TEST_F(ClientNetTransformTests, ClientSetsLocalTmWhenParentIsSet)
  185. {
  186. m_root->m_entity->Activate();
  187. m_child->m_entity->Activate();
  188. SetTranslationOnNetworkTransform(m_root->m_entity, AZ::Vector3::CreateOne());
  189. SetParentIdOnNetworkTransform(m_child->m_entity, NetEntityId{ 1 });
  190. SetTranslationOnNetworkTransform(m_child->m_entity, AZ::Vector3::CreateZero());
  191. AZ::EntityBus::Broadcast(&AZ::EntityBus::Events::OnEntityActivated, m_root->m_entity->GetId());
  192. MultiplayerTick();
  193. EXPECT_EQ(
  194. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->GetWorldTM().GetTranslation(),
  195. AZ::Vector3::CreateOne()
  196. );
  197. EXPECT_EQ(
  198. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->GetLocalTM().GetTranslation(),
  199. AZ::Vector3::CreateZero()
  200. );
  201. }
  202. TEST_F(ClientNetTransformTests, ClientSetsWorldTmWhenParentIsNotSet)
  203. {
  204. m_root->m_entity->Activate();
  205. m_child->m_entity->Activate();
  206. SetTranslationOnNetworkTransform(m_root->m_entity, AZ::Vector3::CreateOne());
  207. SetTranslationOnNetworkTransform(m_child->m_entity, AZ::Vector3::CreateZero());
  208. AZ::EntityBus::Broadcast(&AZ::EntityBus::Events::OnEntityActivated, m_root->m_entity->GetId());
  209. MultiplayerTick();
  210. EXPECT_EQ(
  211. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->GetWorldTM().GetTranslation(),
  212. AZ::Vector3::CreateZero()
  213. );
  214. EXPECT_EQ(
  215. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->GetLocalTM().GetTranslation(),
  216. AZ::Vector3::CreateZero()
  217. );
  218. }
  219. TEST_F(ClientNetTransformTests, ChildFollowsWhenParentMovesOnServer)
  220. {
  221. m_root->m_entity->Activate();
  222. m_child->m_entity->Activate();
  223. SetTranslationOnNetworkTransform(m_root->m_entity, AZ::Vector3::CreateOne());
  224. SetParentIdOnNetworkTransform(m_child->m_entity, NetEntityId{ 1 });
  225. SetTranslationOnNetworkTransform(m_child->m_entity, AZ::Vector3::CreateZero());
  226. AZ::EntityBus::Broadcast(&AZ::EntityBus::Events::OnEntityActivated, m_root->m_entity->GetId());
  227. MultiplayerTick();
  228. // now parent moves
  229. SetTranslationOnNetworkTransform(m_root->m_entity, AZ::Vector3::CreateOne() * 2.f);
  230. MultiplayerTick();
  231. EXPECT_EQ(
  232. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->GetWorldTM().GetTranslation(),
  233. AZ::Vector3::CreateOne() * 2.f
  234. );
  235. EXPECT_EQ(
  236. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->GetLocalTM().GetTranslation(),
  237. AZ::Vector3::CreateZero()
  238. );
  239. }
  240. TEST_F(ClientNetTransformTests, ChildAttachesToParentIfParentIdIsSetBeforeActivation)
  241. {
  242. m_root->m_entity->Activate();
  243. SetTranslationOnNetworkTransform(m_root->m_entity, AZ::Vector3::CreateOne());
  244. SetParentIdOnNetworkTransform(m_child->m_entity, NetEntityId{ 1 });
  245. SetTranslationOnNetworkTransform(m_child->m_entity, AZ::Vector3::CreateZero());
  246. m_child->m_entity->Activate();
  247. AZ::EntityBus::Broadcast(&AZ::EntityBus::Events::OnEntityActivated, m_root->m_entity->GetId());
  248. MultiplayerTick();
  249. EXPECT_EQ(
  250. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->GetParentId(),
  251. AZ::EntityId(1)
  252. );
  253. }
  254. TEST_F(ClientNetTransformTests, CorrectionSyncsTransform)
  255. {
  256. m_root->m_entity->Activate();
  257. m_child->m_entity->Activate();
  258. SetTranslationOnNetworkTransform(m_root->m_entity, AZ::Vector3::CreateOne());
  259. SetParentIdOnNetworkTransform(m_child->m_entity, NetEntityId{ 1 });
  260. m_root->m_entity->FindComponent<NetBindComponent>()->NotifyCorrection();
  261. EXPECT_EQ(m_root->m_entity->GetTransform()->GetWorldTranslation(), AZ::Vector3::CreateOne());
  262. SetTranslationOnNetworkTransform(m_child->m_entity, AZ::Vector3::CreateOne());
  263. m_child->m_entity->FindComponent<NetBindComponent>()->NotifyCorrection();
  264. EXPECT_EQ(m_child->m_entity->GetTransform()->GetLocalTranslation(), AZ::Vector3::CreateOne());
  265. }
  266. }