NetworkHierarchyChildComponent.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Serialization/EditContext.h>
  9. #include <AzFramework/Components/TransformComponent.h>
  10. #include <Multiplayer/IMultiplayer.h>
  11. #include <Multiplayer/Components/NetBindComponent.h>
  12. #include <Multiplayer/Components/NetworkHierarchyBus.h>
  13. #include <Multiplayer/Components/NetworkHierarchyChildComponent.h>
  14. #include <Multiplayer/Components/NetworkHierarchyRootComponent.h>
  15. namespace Multiplayer
  16. {
  17. void NetworkHierarchyChildComponent::Reflect(AZ::ReflectContext* context)
  18. {
  19. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
  20. if (serializeContext)
  21. {
  22. serializeContext->Class<NetworkHierarchyChildComponent, NetworkHierarchyChildComponentBase>()
  23. ->Version(1);
  24. if (AZ::EditContext* editContext = serializeContext->GetEditContext())
  25. {
  26. editContext->Class<NetworkHierarchyChildComponent>(
  27. "Network Hierarchy Child", "Declares a network dependency on the root of this hierarchy.")
  28. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  29. ->Attribute(AZ::Edit::Attributes::Category, "Multiplayer")
  30. ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
  31. ;
  32. }
  33. }
  34. NetworkHierarchyChildComponentBase::Reflect(context);
  35. }
  36. void NetworkHierarchyChildComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  37. {
  38. required.push_back(AZ_CRC_CE("NetworkTransformComponent"));
  39. }
  40. void NetworkHierarchyChildComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  41. {
  42. provided.push_back(AZ_CRC_CE("NetworkHierarchyChildComponent"));
  43. provided.push_back(AZ_CRC_CE("MultiplayerInputDriver"));
  44. }
  45. void NetworkHierarchyChildComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  46. {
  47. incompatible.push_back(AZ_CRC_CE("NetworkHierarchyChildComponent"));
  48. incompatible.push_back(AZ_CRC_CE("NetworkHierarchyRootComponent"));
  49. }
  50. NetworkHierarchyChildComponent::NetworkHierarchyChildComponent()
  51. : m_childChangedHandler([this](AZ::ChildChangeType type, AZ::EntityId child) { OnChildChanged(type, child); })
  52. , m_hierarchyRootNetIdChanged([this](NetEntityId rootNetId) {OnHierarchyRootNetIdChanged(rootNetId); })
  53. {
  54. }
  55. void NetworkHierarchyChildComponent::OnInit()
  56. {
  57. }
  58. void NetworkHierarchyChildComponent::OnActivate([[maybe_unused]] EntityIsMigrating entityIsMigrating)
  59. {
  60. m_isHierarchyEnabled = true;
  61. HierarchyRootAddEvent(m_hierarchyRootNetIdChanged);
  62. NetworkHierarchyRequestBus::Handler::BusConnect(GetEntityId());
  63. if (AzFramework::TransformComponent* transformComponent = GetEntity()->FindComponent<AzFramework::TransformComponent>())
  64. {
  65. transformComponent->BindChildChangedEventHandler(m_childChangedHandler);
  66. }
  67. }
  68. void NetworkHierarchyChildComponent::OnDeactivate([[maybe_unused]] EntityIsMigrating entityIsMigrating)
  69. {
  70. m_isHierarchyEnabled = false;
  71. if (m_rootEntity)
  72. {
  73. if (NetworkHierarchyRootComponent* root = m_rootEntity->FindComponent<NetworkHierarchyRootComponent>())
  74. {
  75. root->RebuildHierarchy();
  76. }
  77. }
  78. NotifyChildrenHierarchyDisbanded();
  79. NetworkHierarchyRequestBus::Handler::BusDisconnect();
  80. }
  81. bool NetworkHierarchyChildComponent::IsHierarchyEnabled() const
  82. {
  83. return m_isHierarchyEnabled;
  84. }
  85. bool NetworkHierarchyChildComponent::IsHierarchicalChild() const
  86. {
  87. return GetHierarchyRoot() != InvalidNetEntityId;
  88. }
  89. AZ::Entity* NetworkHierarchyChildComponent::GetHierarchicalRoot() const
  90. {
  91. return m_rootEntity;
  92. }
  93. AZStd::vector<AZ::Entity*> NetworkHierarchyChildComponent::GetHierarchicalEntities() const
  94. {
  95. if (m_rootEntity)
  96. {
  97. return m_rootEntity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities();
  98. }
  99. return {};
  100. }
  101. void NetworkHierarchyChildComponent::BindNetworkHierarchyChangedEventHandler(NetworkHierarchyChangedEvent::Handler& handler)
  102. {
  103. handler.Connect(m_networkHierarchyChangedEvent);
  104. }
  105. void NetworkHierarchyChildComponent::BindNetworkHierarchyLeaveEventHandler(NetworkHierarchyLeaveEvent::Handler& handler)
  106. {
  107. handler.Connect(m_networkHierarchyLeaveEvent);
  108. }
  109. void NetworkHierarchyChildComponent::SetTopLevelHierarchyRootEntity(AZ::Entity* previousHierarchyRoot, AZ::Entity* newHierarchyRoot)
  110. {
  111. if (newHierarchyRoot)
  112. {
  113. if (m_rootEntity != newHierarchyRoot)
  114. {
  115. m_rootEntity = newHierarchyRoot;
  116. const NetEntityId netRootId = GetNetworkEntityManager()->GetNetEntityIdById(m_rootEntity->GetId());
  117. TrySetControllerRoot(netRootId);
  118. GetNetBindComponent()->SetOwningConnectionId(m_rootEntity->FindComponent<NetBindComponent>()->GetOwningConnectionId());
  119. m_networkHierarchyChangedEvent.Signal(m_rootEntity->GetId());
  120. }
  121. }
  122. else if ((previousHierarchyRoot && m_rootEntity == previousHierarchyRoot) || !previousHierarchyRoot)
  123. {
  124. m_rootEntity = nullptr;
  125. TrySetControllerRoot(InvalidNetEntityId);
  126. GetNetBindComponent()->SetOwningConnectionId(m_previousOwningConnectionId);
  127. m_networkHierarchyLeaveEvent.Signal();
  128. NotifyChildrenHierarchyDisbanded();
  129. }
  130. }
  131. void NetworkHierarchyChildComponent::TrySetControllerRoot([[maybe_unused]] const NetEntityId rootNetId)
  132. {
  133. #if AZ_TRAIT_SERVER
  134. if (HasController() && GetNetBindComponent()->GetNetEntityRole() == NetEntityRole::Authority)
  135. {
  136. NetworkHierarchyChildComponentController* controller = static_cast<NetworkHierarchyChildComponentController*>(GetController());
  137. controller->SetHierarchyRoot(rootNetId);
  138. }
  139. #endif
  140. }
  141. void NetworkHierarchyChildComponent::SetOwningConnectionId(AzNetworking::ConnectionId connectionId)
  142. {
  143. NetworkHierarchyChildComponentBase::SetOwningConnectionId(connectionId);
  144. if (IsHierarchicalChild() == false)
  145. {
  146. m_previousOwningConnectionId = connectionId;
  147. }
  148. }
  149. void NetworkHierarchyChildComponent::OnChildChanged([[maybe_unused]] AZ::ChildChangeType type, [[maybe_unused]] AZ::EntityId child)
  150. {
  151. if (m_rootEntity)
  152. {
  153. if (NetworkHierarchyRootComponent* root = m_rootEntity->FindComponent<NetworkHierarchyRootComponent>())
  154. {
  155. root->RebuildHierarchy();
  156. }
  157. }
  158. }
  159. void NetworkHierarchyChildComponent::OnHierarchyRootNetIdChanged(NetEntityId rootNetId)
  160. {
  161. ConstNetworkEntityHandle rootHandle = GetNetworkEntityManager()->GetEntity(rootNetId);
  162. if (rootHandle.Exists())
  163. {
  164. AZ::Entity* newRoot = rootHandle.GetEntity();
  165. if (m_rootEntity != newRoot)
  166. {
  167. m_rootEntity = newRoot;
  168. m_previousOwningConnectionId = GetNetBindComponent()->GetOwningConnectionId();
  169. GetNetBindComponent()->SetOwningConnectionId(m_rootEntity->FindComponent<NetBindComponent>()->GetOwningConnectionId());
  170. m_networkHierarchyChangedEvent.Signal(m_rootEntity->GetId());
  171. }
  172. }
  173. else
  174. {
  175. GetNetBindComponent()->SetOwningConnectionId(m_previousOwningConnectionId);
  176. m_isHierarchyEnabled = false;
  177. m_rootEntity = nullptr;
  178. }
  179. }
  180. void NetworkHierarchyChildComponent::NotifyChildrenHierarchyDisbanded()
  181. {
  182. AZ::ComponentApplicationRequests* componentApplication = AZ::Interface<AZ::ComponentApplicationRequests>::Get();
  183. AZStd::vector<AZ::EntityId> allChildren;
  184. AZ::TransformBus::EventResult(allChildren, GetEntityId(), &AZ::TransformBus::Events::GetChildren);
  185. for (const AZ::EntityId& childEntityId : allChildren)
  186. {
  187. if (const AZ::Entity* childEntity = componentApplication->FindEntity(childEntityId))
  188. {
  189. if (auto* hierarchyChildComponent = childEntity->FindComponent<NetworkHierarchyChildComponent>())
  190. {
  191. hierarchyChildComponent->SetTopLevelHierarchyRootEntity(nullptr, nullptr);
  192. }
  193. else if (auto* hierarchyRootComponent = childEntity->FindComponent<NetworkHierarchyRootComponent>())
  194. {
  195. hierarchyRootComponent->SetTopLevelHierarchyRootEntity(nullptr, nullptr);
  196. }
  197. }
  198. }
  199. }
  200. }