Kaynağa Gözat

Merge pull request #91 from aws-lumberyard-dev/GHI_62_MultiplayerTemplateClientServerSplit

Client/Server Split: Merging MultiplayerSample into MultiplayerTemplate
Gene Walters 2 yıl önce
ebeveyn
işleme
fb4ac8ef31

+ 8 - 0
Templates/Multiplayer/Template/Gem/Code/${NameLower}_autogen_files.cmake

@@ -11,4 +11,12 @@ set(FILES
     ${LY_ROOT_FOLDER}/Gems/Multiplayer/Code/Include/Multiplayer/AutoGen/AutoComponent_Source.jinja
     ${LY_ROOT_FOLDER}/Gems/Multiplayer/Code/Include/Multiplayer/AutoGen/AutoComponentTypes_Header.jinja
     ${LY_ROOT_FOLDER}/Gems/Multiplayer/Code/Include/Multiplayer/AutoGen/AutoComponentTypes_Source.jinja
+    Source/AutoGen/NetworkAiComponent.AutoComponent.xml
+    Source/AutoGen/NetworkAnimationComponent.AutoComponent.xml
+    Source/AutoGen/NetworkHealthComponent.AutoComponent.xml
+    Source/AutoGen/NetworkPlayerSpawnerComponent.AutoComponent.xml
+    Source/AutoGen/NetworkRandomComponent.AutoComponent.xml
+    Source/AutoGen/NetworkWeaponsComponent.AutoComponent.xml
+    Source/AutoGen/NetworkSimplePlayerCameraComponent.AutoComponent.xml
+    Source/AutoGen/NetworkPlayerMovementComponent.AutoComponent.xml
 )

+ 0 - 8
Templates/Multiplayer/Template/Gem/Code/${NameLower}_files.cmake

@@ -7,14 +7,6 @@
 
 set(FILES
     Include/NetworkPrefabSpawnerInterface.h
-    Source/AutoGen/NetworkAiComponent.AutoComponent.xml
-    Source/AutoGen/NetworkAnimationComponent.AutoComponent.xml
-    Source/AutoGen/NetworkHealthComponent.AutoComponent.xml
-    Source/AutoGen/NetworkPlayerSpawnerComponent.AutoComponent.xml
-    Source/AutoGen/NetworkRandomComponent.AutoComponent.xml
-    Source/AutoGen/NetworkWeaponsComponent.AutoComponent.xml
-    Source/AutoGen/NetworkSimplePlayerCameraComponent.AutoComponent.xml
-    Source/AutoGen/NetworkPlayerMovementComponent.AutoComponent.xml
     Source/Components/ExampleFilteredEntityComponent.h
     Source/Components/ExampleFilteredEntityComponent.cpp
     Source/Components/NetworkAiComponent.cpp

+ 120 - 11
Templates/Multiplayer/Template/Gem/Code/CMakeLists.txt

@@ -8,11 +8,11 @@
 o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}")
 
 ly_add_target(
-    NAME ${Name}.Static STATIC
+    NAME ${Name}.Client.Static STATIC
     NAMESPACE Gem
     FILES_CMAKE
-        ${NameLower}_files.cmake
         ${NameLower}_autogen_files.cmake
+        ${NameLower}_files.cmake
         ${pal_dir}/${NameLower}_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
     INCLUDE_DIRECTORIES
         PRIVATE
@@ -22,21 +22,87 @@ ly_add_target(
             Include
     BUILD_DEPENDENCIES
         PUBLIC
-            AZ::AzGameFramework
-            AZ::AzNetworking
-            Gem::Multiplayer
+            Gem::DebugDraw
+            Gem::LyShine
+            Gem::StartingPointInput
             Gem::EMotionFXStaticLib
             Gem::PhysX
+            Gem::Multiplayer
+        PRIVATE
+            Gem::LmbrCentral.Static
+            Gem::Multiplayer.Client.Static
+            Gem::PhysX.Static
+            Gem::DebugDraw.Static
+            Gem::ImGui.Static
+            Gem::LyShine.Static
+            Gem::GameState.Static
+    AUTOGEN_RULES
+        *.AutoComponent.xml,AutoComponent_Header.jinja,$path/$fileprefix.AutoComponent.h
+        *.AutoComponent.xml,AutoComponent_Source.jinja,$path/$fileprefix.AutoComponent.cpp
+        *.AutoComponent.xml,AutoComponentTypes_Header.jinja,$path/AutoComponentTypes.h
+        *.AutoComponent.xml,AutoComponentTypes_Source.jinja,$path/AutoComponentTypes.cpp
+)
+
+ly_add_target(
+    NAME ${Name}.Server.Static STATIC
+    NAMESPACE Gem
+    FILES_CMAKE
+        ${NameLower}_autogen_files.cmake
+        ${NameLower}_files.cmake
+        ${pal_dir}/${NameLower}_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
+    INCLUDE_DIRECTORIES
+        PRIVATE
+            Source
+            .
+        PUBLIC
+            Include
+    BUILD_DEPENDENCIES
+        PUBLIC
             Gem::StartingPointInput
+            Gem::EMotionFXStaticLib
+            Gem::PhysX
+            Gem::Multiplayer
+        PRIVATE
+            Gem::LmbrCentral.Static
+            Gem::Multiplayer.Server.Static
+            Gem::PhysX.Static
+            Gem::GameState.Static
+    AUTOGEN_RULES
+        *.AutoComponent.xml,AutoComponent_Header.jinja,$path/$fileprefix.AutoComponent.h
+        *.AutoComponent.xml,AutoComponent_Source.jinja,$path/$fileprefix.AutoComponent.cpp
+        *.AutoComponent.xml,AutoComponentTypes_Header.jinja,$path/AutoComponentTypes.h
+        *.AutoComponent.xml,AutoComponentTypes_Source.jinja,$path/AutoComponentTypes.cpp
+)
+
+ly_add_target(
+    NAME ${Name}.Unified.Static STATIC
+    NAMESPACE Gem
+    FILES_CMAKE
+        ${NameLower}_autogen_files.cmake
+        ${NameLower}_files.cmake
+        ${pal_dir}/${NameLower}_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
+    INCLUDE_DIRECTORIES
+        PRIVATE
+            Source
+            .
+        PUBLIC
+            Include
+    BUILD_DEPENDENCIES
+        PUBLIC
             Gem::DebugDraw
             Gem::LyShine
+            Gem::StartingPointInput
+            Gem::EMotionFXStaticLib
+            Gem::PhysX
+            Gem::Multiplayer
         PRIVATE
             Gem::LmbrCentral.Static
-            Gem::Multiplayer.Static
+            Gem::Multiplayer.Unified.Static
             Gem::PhysX.Static
             Gem::DebugDraw.Static
             Gem::ImGui.Static
             Gem::LyShine.Static
+            Gem::GameState.Static
     AUTOGEN_RULES
         *.AutoComponent.xml,AutoComponent_Header.jinja,$path/$fileprefix.AutoComponent.h
         *.AutoComponent.xml,AutoComponent_Source.jinja,$path/$fileprefix.AutoComponent.cpp
@@ -44,6 +110,42 @@ ly_add_target(
         *.AutoComponent.xml,AutoComponentTypes_Source.jinja,$path/AutoComponentTypes.cpp
 )
 
+ly_add_target(
+    NAME ${Name}.Client ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
+    NAMESPACE Gem
+    FILES_CMAKE
+        ${NameLower}_shared_files.cmake
+        ../../${NameLower}_asset_files.cmake
+    INCLUDE_DIRECTORIES
+        PRIVATE
+            Source
+            .
+        PUBLIC
+            Include
+    BUILD_DEPENDENCIES
+        PRIVATE
+            Gem::${Name}.Client.Static
+            Gem::Atom_AtomBridge.Static
+)
+
+ly_add_target(
+    NAME ${Name}.Server ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
+    NAMESPACE Gem
+    FILES_CMAKE
+        ${NameLower}_shared_files.cmake
+        ../../${NameLower}_asset_files.cmake
+    INCLUDE_DIRECTORIES
+        PRIVATE
+            Source
+            .
+        PUBLIC
+            Include
+    BUILD_DEPENDENCIES
+        PRIVATE
+            Gem::${Name}.Server.Static
+            Gem::Atom_AtomBridge.Static
+)
+
 ly_add_target(
     NAME ${Name} ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
     NAMESPACE Gem
@@ -58,15 +160,16 @@ ly_add_target(
             Include
     BUILD_DEPENDENCIES
         PRIVATE
-            Gem::${Name}.Static
+            Gem::${Name}.Unified.Static
             Gem::Atom_AtomBridge.Static
 )
 
 # if enabled, ${Name} is used by all kinds of applications
 ly_create_alias(NAME ${Name}.Builders NAMESPACE Gem TARGETS Gem::${Name})
 ly_create_alias(NAME ${Name}.Tools    NAMESPACE Gem TARGETS Gem::${Name})
-ly_create_alias(NAME ${Name}.Clients  NAMESPACE Gem TARGETS Gem::${Name})
-ly_create_alias(NAME ${Name}.Servers  NAMESPACE Gem TARGETS Gem::${Name})
+ly_create_alias(NAME ${Name}.Clients  NAMESPACE Gem TARGETS Gem::${Name}.Client)
+ly_create_alias(NAME ${Name}.Servers  NAMESPACE Gem TARGETS Gem::${Name}.Server)
+ly_create_alias(NAME ${Name}.Unified  NAMESPACE Gem TARGETS Gem::${Name})
 
 ################################################################################
 # Gem dependencies
@@ -80,5 +183,11 @@ if(PAL_TRAIT_BUILD_SERVER_SUPPORTED)
     set_property(GLOBAL APPEND PROPERTY LY_LAUNCHER_SERVER_PROJECTS ${Name})
 endif()
 
-set_property(TARGET ${Name} APPEND PROPERTY GAMELAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS "--console-command-file=\"client.cfg\"")
-set_property(TARGET ${Name} APPEND PROPERTY SERVERLAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS "--console-command-file=\"server.cfg\"")
+# If we build a server, then add the project name to the list of server launcher projects
+if(PAL_TRAIT_BUILD_UNIFIED_SUPPORTED)
+    set_property(GLOBAL APPEND PROPERTY LY_LAUNCHER_UNIFIED_PROJECTS ${Name})
+endif()
+
+set_property(TARGET ${Name} APPEND PROPERTY GAMELAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS "--console-command-file=\"launch_client.cfg\"")
+set_property(TARGET ${Name} APPEND PROPERTY SERVERLAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS "--console-command-file=\"launch_server.cfg\"")
+set_property(TARGET ${Name} APPEND PROPERTY UNIFIEDLAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS "--console-command-file=\"launch_server.cfg\"")

+ 4 - 0
Templates/Multiplayer/Template/Gem/Code/Source/${Name}Module.cpp

@@ -50,4 +50,8 @@ namespace ${SanitizedCppName}
 // DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM
 // The first parameter should be GemName_GemIdLower
 // The second should be the fully qualified name of the class above
+#if defined(AZ_MONOLITHIC_BUILD)
+AZ_DECLARE_MODULE_CLASS(Gem_${SanitizedCppName}_Client, ${SanitizedCppName}::${SanitizedCppName}Module);
+AZ_DECLARE_MODULE_CLASS(Gem_${SanitizedCppName}_Server, ${SanitizedCppName}::${SanitizedCppName}Module);
+#endif
 AZ_DECLARE_MODULE_CLASS(Gem_${SanitizedCppName}, ${SanitizedCppName}::${SanitizedCppName}Module)

+ 1 - 1
Templates/Multiplayer/Template/Gem/Code/Source/AutoGen/NetworkRandomComponent.AutoComponent.xml

@@ -9,6 +9,6 @@
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="MultiplayerAutoComponentSchema.xsd">
 
-    <NetworkProperty Type="uint64_t" Init="0" Name="Seed" ReplicateFrom="Authority" ReplicateTo="Client" Container="Object" IsPublic="true" IsRewindable="false" IsPredictable="false" ExposeToEditor="false" ExposeToScript="false" GenerateEventBindings="false" Description="The RNG seed" />
+    <NetworkProperty Type="uint64_t" Init="0" Name="Seed" ReplicateFrom="Authority" ReplicateTo="Client" Container="Object" IsPublic="true" IsRewindable="false" IsPredictable="true" ExposeToEditor="false" ExposeToScript="false" GenerateEventBindings="false" Description="The RNG seed" />
 
 </Component>

+ 2 - 24
Templates/Multiplayer/Template/Gem/Code/Source/Components/NetworkAiComponent.cpp

@@ -23,30 +23,7 @@ namespace ${SanitizedCppName}
     {
     }
 
-    void NetworkAiComponentController::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
-    {
-        if (GetEnabled())
-        {
-            Multiplayer::LocalPredictionPlayerInputComponentController* playerInputController = GetLocalPredictionPlayerInputComponentController();
-            if (playerInputController != nullptr)
-            {
-                playerInputController->ForceEnableAutonomousUpdate();
-            }
-        }
-    }
-
-    void NetworkAiComponentController::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
-    {
-        if (GetEnabled())
-        {
-            Multiplayer::LocalPredictionPlayerInputComponentController* playerInputController = GetLocalPredictionPlayerInputComponentController();
-            if (playerInputController != nullptr)
-            {
-                playerInputController->ForceDisableAutonomousUpdate();
-            }
-        }
-    }
-
+#if AZ_TRAIT_SERVER
     void NetworkAiComponentController::TickMovement(NetworkPlayerMovementComponentController& movementController, float deltaTime)
     {
         // TODO: Execute this tick only if this component is owned by this endpoint (currently ticks on server only)
@@ -145,4 +122,5 @@ namespace ${SanitizedCppName}
         SetActionIntervalMaxMs(actionIntervalMaxMs);
         m_lcg.SetSeed(seed);
     }
+#endif
 }

+ 7 - 2
Templates/Multiplayer/Template/Gem/Code/Source/Components/NetworkAiComponent.h

@@ -24,18 +24,23 @@ namespace ${SanitizedCppName}
     public:
         NetworkAiComponentController(NetworkAiComponent& parent);
 
-        void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
-        void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
+        void OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {};
+        void OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {};
 
+#if AZ_TRAIT_SERVER
         void TickMovement(NetworkPlayerMovementComponentController& movementController, float deltaTime);
         void TickWeapons(NetworkWeaponsComponentController& weaponsController, float deltaTime);
+#endif
 
     private:
         friend class NetworkStressTestComponentController;
+
+#if AZ_TRAIT_SERVER
         void ConfigureAi(
             float fireIntervalMinMs, float fireIntervalMaxMs, float actionIntervalMinMs, float actionIntervalMaxMs, uint64_t seed);
 
         // TODO: Technically this guy should also be authority to autonomous so we don't roll different values after a migration..
         AZ::SimpleLcgRandom m_lcg;
+#endif
     };
 }

+ 2 - 0
Templates/Multiplayer/Template/Gem/Code/Source/Components/NetworkHealthComponent.cpp

@@ -24,10 +24,12 @@ namespace ${SanitizedCppName}
         ;
     }
 
+#if AZ_TRAIT_SERVER
     void NetworkHealthComponentController::HandleSendHealthDelta([[maybe_unused]] AzNetworking::IConnection* invokingConnection, const float& healthDelta)
     {
         float health = GetHealth();
         health = AZStd::max(0.0f, AZStd::min(GetMaxHealth(), health + healthDelta));
         SetHealth(health);
     }
+#endif
 }

+ 2 - 0
Templates/Multiplayer/Template/Gem/Code/Source/Components/NetworkHealthComponent.h

@@ -20,6 +20,8 @@ namespace ${SanitizedCppName}
         void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
         void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
 
+#if AZ_TRAIT_SERVER
         void HandleSendHealthDelta(AzNetworking::IConnection* invokingConnection, const float& healthDelta) override;
+#endif
     };
 }

+ 2 - 0
Templates/Multiplayer/Template/Gem/Code/Source/Components/NetworkPlayerMovementComponent.cpp

@@ -305,10 +305,12 @@ namespace ${SanitizedCppName}
 
     void NetworkPlayerMovementComponentController::UpdateAI()
     {
+#if AZ_TRAIT_SERVER
         float deltaTime = static_cast<float>(m_updateAI.TimeInQueueMs()) / 1000.f;
         if (m_networkAiComponentController != nullptr)
         {
             m_networkAiComponentController->TickMovement(*this, deltaTime);
         }
+#endif
     }
 } // namespace ${SanitizedCppName}

+ 2 - 0
Templates/Multiplayer/Template/Gem/Code/Source/Components/NetworkRandomComponent.cpp

@@ -41,6 +41,7 @@ namespace ${SanitizedCppName}
     NetworkRandomComponentController::NetworkRandomComponentController(NetworkRandomComponent& parent)
         : NetworkRandomComponentControllerBase(parent)
     {
+#if AZ_TRAIT_SERVER
         if (IsNetEntityRoleAuthority())
         {
             // Setup seed on authority for proxies to pull
@@ -49,6 +50,7 @@ namespace ${SanitizedCppName}
             seedGenerator.GetRandom(seed);
             SetSeed(seed);
         };
+#endif
     }
 
     void NetworkRandomComponentController::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)

+ 22 - 0
Templates/Multiplayer/Template/Gem/Code/Source/Components/NetworkWeaponsComponent.cpp

@@ -14,7 +14,10 @@
 #include <Source/Components/NetworkSimplePlayerCameraComponent.h>
 #include <Source/Weapons/BaseWeapon.h>
 #include <AzCore/Component/TransformBus.h>
+
+#if AZ_TRAIT_CLIENT
 #include <DebugDraw/DebugDrawBus.h>
+#endif
 
 namespace ${SanitizedCppName}
 {
@@ -66,10 +69,12 @@ namespace ${SanitizedCppName}
             ActivationCountsAddEvent(m_activationCountHandler);
         }
 
+#if AZ_TRAIT_CLIENT
         if (m_debugDraw == nullptr)
         {
             m_debugDraw = DebugDraw::DebugDrawRequestBus::FindFirstHandler();
         }
+#endif
     }
 
     void NetworkWeaponsComponent::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
@@ -77,6 +82,7 @@ namespace ${SanitizedCppName}
         ;
     }
 
+#if AZ_TRAIT_CLIENT
     void NetworkWeaponsComponent::HandleSendConfirmHit([[maybe_unused]] AzNetworking::IConnection* invokingConnection, const WeaponIndex& weaponIndex, const HitEvent& hitEvent)
     {
         if (GetWeapon(weaponIndex) == nullptr)
@@ -88,6 +94,7 @@ namespace ${SanitizedCppName}
         WeaponHitInfo weaponHitInfo(*GetWeapon(weaponIndex), hitEvent);
         OnWeaponConfirmHit(weaponHitInfo);
     }
+#endif
 
     void NetworkWeaponsComponent::ActivateWeaponWithParams(WeaponIndex weaponIndex, WeaponState& weaponState, const FireParams& fireParams, bool validateActivations)
     {
@@ -114,6 +121,7 @@ namespace ${SanitizedCppName}
             return;
         }
 
+#if AZ_TRAIT_CLIENT
         if (cl_WeaponsDrawDebug && m_debugDraw)
         {
             m_debugDraw->DrawSphereAtLocation
@@ -132,14 +140,17 @@ namespace ${SanitizedCppName}
                 cl_WeaponsDrawDebugDurationSec
             );
         }
+#endif
     }
 
     void NetworkWeaponsComponent::OnWeaponHit(const WeaponHitInfo& hitInfo)
     {
         if (IsNetEntityRoleAuthority())
         {
+#if AZ_TRAIT_SERVER
             OnWeaponConfirmHit(hitInfo);
             static_cast<NetworkWeaponsComponentController*>(GetController())->SendConfirmHit(hitInfo.m_weapon.GetWeaponIndex(), hitInfo.m_hitEvent);
+#endif
         }
         else
         {
@@ -159,6 +170,7 @@ namespace ${SanitizedCppName}
         {
             const HitEntity& hitEntity = hitInfo.m_hitEvent.m_hitEntities[i];
 
+#if AZ_TRAIT_CLIENT
             if (cl_WeaponsDrawDebug && m_debugDraw)
             {
                 m_debugDraw->DrawSphereAtLocation
@@ -169,6 +181,7 @@ namespace ${SanitizedCppName}
                     cl_WeaponsDrawDebugDurationSec
                 );
             }
+#endif
 
             AZLOG
             (
@@ -184,6 +197,8 @@ namespace ${SanitizedCppName}
 
     void NetworkWeaponsComponent::OnWeaponConfirmHit(const WeaponHitInfo& hitInfo)
     {
+
+#if AZ_TRAIT_SERVER
         if (IsNetEntityRoleAuthority())
         {
             for (const HitEntity& hitEntity : hitInfo.m_hitEvent.m_hitEntities)
@@ -220,6 +235,7 @@ namespace ${SanitizedCppName}
                 }
             }
         }
+#endif
 
         // If we're a simulated weapon, or if the weapon is not predictive, then issue material hit effects since the predicted callback above will not get triggered
         [[maybe_unused]] bool shouldIssueMaterialEffects = !HasController() || !hitInfo.m_weapon.GetParams().m_locallyPredicted;
@@ -228,6 +244,7 @@ namespace ${SanitizedCppName}
         {
             const HitEntity& hitEntity = hitInfo.m_hitEvent.m_hitEntities[i];
 
+#if AZ_TRAIT_CLIENT
             if (cl_WeaponsDrawDebug && m_debugDraw)
             {
                 m_debugDraw->DrawSphereAtLocation
@@ -238,6 +255,7 @@ namespace ${SanitizedCppName}
                     cl_WeaponsDrawDebugDurationSec
                 );
             }
+#endif
 
             AZLOG
             (
@@ -409,11 +427,13 @@ namespace ${SanitizedCppName}
                 GetParent().ActivateWeaponWithParams(
                     aznumeric_cast<WeaponIndex>(weaponIndexInt), weaponState, fireParams, validateActivations);
 
+#if AZ_TRAIT_SERVER
                 if (IsNetEntityRoleAuthority())
                 {
                     SetActivationParams(weaponIndexInt, fireParams);
                     SetActivationCounts(weaponIndexInt, weaponState.m_activationCount);
                 }
+#endif
             }
             weapon->UpdateWeaponState(weaponState, deltaTime);
         }
@@ -491,10 +511,12 @@ namespace ${SanitizedCppName}
 
     void NetworkWeaponsComponentController::UpdateAI()
     {
+#if AZ_TRAIT_SERVER
         float deltaTime = static_cast<float>(m_updateAI.TimeInQueueMs()) / 1000.f;
         if (m_networkAiComponentController != nullptr)
         {
             m_networkAiComponentController->TickWeapons(*this, deltaTime);
         }
+#endif
     }
 } // namespace ${SanitizedCppName}

+ 2 - 0
Templates/Multiplayer/Template/Gem/Code/Source/Components/NetworkWeaponsComponent.h

@@ -39,7 +39,9 @@ namespace ${SanitizedCppName}
         void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
         void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
 
+#if AZ_TRAIT_CLIENT
         void HandleSendConfirmHit(AzNetworking::IConnection* invokingConnection, const WeaponIndex& weaponIndex, const HitEvent& hitEvent) override;
+#endif
         void ActivateWeaponWithParams(WeaponIndex weaponIndex, WeaponState& weaponState, const FireParams& fireParams, bool validateActivations);
 
         IWeapon* GetWeapon(WeaponIndex weaponIndex) const;

+ 8 - 1
Templates/Multiplayer/Template/Gem/Code/Source/Weapons/WeaponGathers.cpp

@@ -10,9 +10,12 @@
 #include <AzFramework/Physics/PhysicsScene.h>
 #include <AzCore/Component/Component.h>
 #include <AzCore/Console/ILogger.h>
-#include <DebugDraw/DebugDrawBus.h>
 #include <Source/Weapons/SceneQuery.h>
 
+#if AZ_TRAIT_CLIENT
+#include <DebugDraw/DebugDrawBus.h>
+#endif
+
 namespace ${SanitizedCppName}
 {
     AZ_CVAR(uint32_t, bg_MultitraceNumTraceSegments, 3, nullptr, AZ::ConsoleFunctorFlags::Null, "The number of segments to use when performing multitrace casts");
@@ -61,6 +64,7 @@ namespace ${SanitizedCppName}
             collisionGroup, filteredNetEntityIds, gatherParams.GetCurrentShapeConfiguration());
         SceneQuery::WorldIntersect(intersectShape, filter, outResults);
 
+#if AZ_TRAIT_CLIENT
         if (bg_DrawPhysicsRaycasts)
         {
             DebugDraw::DebugDrawRequestBus::Broadcast
@@ -72,6 +76,7 @@ namespace ${SanitizedCppName}
                 10.0f
             );
         }
+#endif
 
         return true;
     }
@@ -122,6 +127,7 @@ namespace ${SanitizedCppName}
                 hitMultiple, collisionGroup, filteredNetEntityIds, gatherParams.GetCurrentShapeConfiguration());
             SceneQuery::WorldIntersect(gatherParams.m_gatherShape, filter, outResults);
 
+#if AZ_TRAIT_CLIENT
             if (bg_DrawPhysicsRaycasts)
             {
                 DebugDraw::DebugDrawRequestBus::Broadcast
@@ -133,6 +139,7 @@ namespace ${SanitizedCppName}
                     10.0f
                 );
             }
+#endif
 
             // Terminate the loop if we hit something
             if (((outResults.size() > 0) && !gatherParams.m_multiHit) || (travelDistance.GetLengthSq() > maxTravelDistanceSq))