NetworkTeleportComponent.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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
  3. * this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "NetworkTeleportComponent.h"
  9. #include <GameplayEffectsNotificationBus.h>
  10. #include <Multiplayer/Components/NetworkTransformComponent.h>
  11. #include <Source/Components/NetworkTeleportCompatibleComponent.h>
  12. #include <AzCore/Component/TransformBus.h>
  13. #include <AzCore/Component/ComponentApplicationBus.h>
  14. #include <AzCore/Component/Entity.h>
  15. #include <AzCore/Serialization/EditContext.h>
  16. #include <AzCore/Serialization/SerializeContext.h>
  17. #include <AzCore/Interface/Interface.h>
  18. #include <AzFramework/Physics/RigidBodyBus.h>
  19. #include <AzFramework/Physics/PhysicsSystem.h>
  20. namespace MultiplayerSample
  21. {
  22. void NetworkTeleportComponent::Reflect(AZ::ReflectContext* reflection)
  23. {
  24. if (auto serializationContext = azrtti_cast<AZ::SerializeContext*>(reflection))
  25. {
  26. serializationContext->Class<NetworkTeleportComponent, NetworkTeleportComponentBase>()
  27. ->Version(4);
  28. NetworkTeleportComponentBase::Reflect(reflection);
  29. }
  30. }
  31. void NetworkTeleportComponent::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
  32. {
  33. #if AZ_TRAIT_CLIENT
  34. m_effect = GetTeleportEffect();
  35. m_effect.Initialize();
  36. #endif
  37. }
  38. void NetworkTeleportComponent::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
  39. {
  40. #if AZ_TRAIT_CLIENT
  41. // Clean up the teleport effect emitter.
  42. m_effect = {};
  43. #endif
  44. }
  45. #if AZ_TRAIT_CLIENT
  46. void NetworkTeleportComponent::HandleNotifyTeleport([[maybe_unused]] AzNetworking::IConnection* invokingConnection)
  47. {
  48. m_effect.TriggerEffect(GetEntity()->GetTransform()->GetWorldTM());
  49. }
  50. #endif
  51. // Controller
  52. NetworkTeleportComponentController::NetworkTeleportComponentController(NetworkTeleportComponent& parent)
  53. : NetworkTeleportComponentControllerBase(parent)
  54. , m_enterTrigger([this](
  55. AzPhysics::SimulatedBodyHandle bodyHandle,
  56. const AzPhysics::TriggerEvent& triggerEvent)
  57. {
  58. this->OnTriggerEnter(bodyHandle, triggerEvent);
  59. })
  60. {
  61. }
  62. void NetworkTeleportComponentController::OnPhysicsEnabled(const AZ::EntityId& entityId)
  63. {
  64. auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get();
  65. if (physicsSystem)
  66. {
  67. auto [sceneHandle, bodyHandle] = physicsSystem->FindAttachedBodyHandleFromEntityId(entityId);
  68. AzPhysics::SimulatedBodyEvents::RegisterOnTriggerEnterHandler(
  69. sceneHandle, bodyHandle, m_enterTrigger);
  70. }
  71. }
  72. void NetworkTeleportComponentController::OnPhysicsDisabled([[maybe_unused]] const AZ::EntityId& entityId)
  73. {
  74. m_enterTrigger.Disconnect();
  75. }
  76. void NetworkTeleportComponentController::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
  77. {
  78. Physics::RigidBodyNotificationBus::Handler::BusConnect(GetEntity()->GetId());
  79. }
  80. void NetworkTeleportComponentController::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
  81. {
  82. Physics::RigidBodyNotificationBus::Handler::BusDisconnect();
  83. m_enterTrigger.Disconnect();
  84. }
  85. void NetworkTeleportComponentController::OnTriggerEnter(
  86. [[maybe_unused]] AzPhysics::SimulatedBodyHandle bodyHandle, const AzPhysics::TriggerEvent& triggerEvent)
  87. {
  88. if (triggerEvent.m_otherBody)
  89. {
  90. AZ::Vector3 teleportLocation = GetDestinationVector();
  91. AZ_TracePrintf("Teleporter", "Destination point X, Y is: %f, %f\n",
  92. teleportLocation.GetX(), teleportLocation.GetY());
  93. AZ::Entity* otherEntity = GetCollidingEntity(triggerEvent.m_otherBody);
  94. TeleportPlayer(teleportLocation, otherEntity);
  95. }
  96. }
  97. AZ::Entity* NetworkTeleportComponentController::GetCollidingEntity(
  98. AzPhysics::SimulatedBody* collidingBody) const
  99. {
  100. AZ::Entity* collidingEntity = nullptr;
  101. if (collidingBody)
  102. {
  103. AZ::EntityId collidingEntityId = collidingBody->GetEntityId();
  104. AZ::ComponentApplicationBus::BroadcastResult(
  105. collidingEntity, &AZ::ComponentApplicationBus::Events::FindEntity, collidingEntityId);
  106. }
  107. return collidingEntity;
  108. }
  109. AZ::Vector3 NetworkTeleportComponentController::GetDestinationVector() const
  110. {
  111. AZ::Vector3 location = GetEntity()->GetTransform()->
  112. GetWorldTM().GetTranslation();
  113. AZ::EntityId destination = GetDestination();
  114. AZ::TransformBus::EventResult(location, destination,
  115. &AZ::TransformBus::Events::GetWorldTranslation);
  116. return location;
  117. }
  118. void NetworkTeleportComponentController::TeleportPlayer(
  119. [[maybe_unused]] const AZ::Vector3& vector, AZ::Entity* entity)
  120. {
  121. if (entity)
  122. {
  123. MultiplayerSample::NetworkTeleportCompatibleComponent* teleportable =
  124. entity->FindComponent<MultiplayerSample::NetworkTeleportCompatibleComponent>();
  125. if (teleportable)
  126. {
  127. #if AZ_TRAIT_SERVER
  128. NotifyTeleport();
  129. teleportable->Teleport(vector);
  130. #endif
  131. }
  132. else
  133. {
  134. AZ_TracePrintf("Teleporter", "colliding entity %s is not teleport compatible! NoOp.\n",
  135. entity->GetName().c_str());
  136. }
  137. }
  138. }
  139. } // namespace MultiplayerSample