Bladeren bron

Merge pull request #375 from aws-lumberyard-dev/qingtao/gitflow_230420_o3de-multiplayersample

Qingtao/gitflow_230420_o3de-multiplayersample
Qing Tao 2 jaren geleden
bovenliggende
commit
8ab4756a4f
27 gewijzigde bestanden met toevoegingen van 749 en 79 verwijderingen
  1. 3 5
      Gem/Code/Source/AutoGen/EnergyBallComponent.AutoComponent.xml
  2. 110 0
      Gem/Code/Source/Components/BackgroundMusicComponent.cpp
  3. 42 0
      Gem/Code/Source/Components/BackgroundMusicComponent.h
  4. 112 18
      Gem/Code/Source/Components/Multiplayer/EnergyBallComponent.cpp
  5. 15 1
      Gem/Code/Source/Components/Multiplayer/EnergyBallComponent.h
  6. 63 17
      Gem/Code/Source/Effects/GameEffect.cpp
  7. 10 9
      Gem/Code/Source/MultiplayerSampleModule.cpp
  8. 3 0
      Gem/Code/multiplayersample_files.cmake
  9. 52 9
      Levels/NewStarbase/NewStarbase.prefab
  10. 6 7
      Registry/settings.multiplayersample_gamelauncher.setreg
  11. 6 7
      Registry/settings.multiplayersample_unifiedlauncher.setreg
  12. 3 0
      Sounds/wwise/1070395499.wem
  13. 3 0
      Sounds/wwise/1073420800.wem
  14. 3 0
      Sounds/wwise/115250578.wem
  15. 3 0
      Sounds/wwise/655023540.wem
  16. 2 2
      Sounds/wwise/MultiplayerSample_SoundBank.bnk
  17. 192 0
      Sounds/wwise_project/Actor-Mixer Hierarchy/AMPS/LVL.wwu
  18. 14 0
      Sounds/wwise_project/Actor-Mixer Hierarchy/AMPS/MX.wwu
  19. 63 3
      Sounds/wwise_project/Events/AMPS/AMB.wwu
  20. 11 1
      Sounds/wwise_project/Events/Default O3DE Work Unit.wwu
  21. 3 0
      Sounds/wwise_project/Originals/SFX/Beauty Flow.wav
  22. 3 0
      Sounds/wwise_project/Originals/SFX/Future Gladiator.wav
  23. 3 0
      Sounds/wwise_project/Originals/SFX/Rocket.wav
  24. 3 0
      Sounds/wwise_project/Originals/SFX/incompetech/Dream Catcher.wav
  25. 12 0
      Sounds/wwise_project/Soundcaster Sessions/Default Work Unit.wwu
  26. 0 0
      credits.md
  27. 9 0
      libs/gameaudio/wwise/multiplayersample_controls.xml

+ 3 - 5
Gem/Code/Source/AutoGen/EnergyBallComponent.AutoComponent.xml

@@ -17,7 +17,9 @@
     <ArchetypeProperty Type="GatherParams" Name="GatherParams" Init="" ExposeToEditor="true" Description="Specifies the types of intersections to test for on the projectile" />
     <ArchetypeProperty Type="HitEffect" Name="HitEffect" Init="" ExposeToEditor="true" Description="Specifies the damage effects to apply on hit" />
 
-    <RemoteProcedure Name="RPC_LaunchBall" InvokeFrom="Server" HandleOn="Authority" IsPublic="true" IsReliable="true" GenerateEventBindings="true" Description="Launching an energy from a specified position in a specified direction.">
+    <NetworkProperty Type="bool" Name="BallActive" Init="false" ReplicateFrom="Authority" ReplicateTo="Client" Container="Object" IsPublic="true" IsRewindable="true" IsPredictable="false" ExposeToScript="false" ExposeToEditor="false" GenerateEventBindings="true" Description="Track whether or not the energy ball is currently active" />
+
+  <RemoteProcedure Name="RPC_LaunchBall" InvokeFrom="Server" HandleOn="Authority" IsPublic="true" IsReliable="true" GenerateEventBindings="true" Description="Launch an energy ball from a specified position in a specified direction.">
         <Param Type="AZ::Vector3" Name="StartingPosition"/>
         <Param Type="AZ::Vector3" Name="Direction"/>
         <Param Type="Multiplayer::NetEntityId" Name="OwningNetEntityId" />
@@ -25,10 +27,6 @@
 
     <RemoteProcedure Name="RPC_KillBall" InvokeFrom="Server" HandleOn="Authority" IsPublic="true" IsReliable="true" GenerateEventBindings="true" Description="Kills a launched energy ball." />
 
-    <RemoteProcedure Name="RPC_BallLaunched" InvokeFrom="Authority" HandleOn="Client" IsPublic="true" IsReliable="true" GenerateEventBindings="true" Description="Triggered on clients whenever an energy ball launches.">
-        <Param Type="AZ::Vector3" Name="Location"/>
-    </RemoteProcedure>
-
     <RemoteProcedure Name="RPC_BallExplosion" InvokeFrom="Authority" HandleOn="Client" IsPublic="true" IsReliable="true" GenerateEventBindings="true" Description="Triggered on clients whenever an energy ball explodes.">
         <Param Type="HitEvent" Name="HitEvent"/>
     </RemoteProcedure>

+ 110 - 0
Gem/Code/Source/Components/BackgroundMusicComponent.cpp

@@ -0,0 +1,110 @@
+/*
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <Source/Components/BackgroundMusicComponent.h>
+#include <AzCore/Serialization/EditContext.h>
+#include <AzCore/Serialization/SerializeContext.h>
+#include <LmbrCentral/Audio/AudioProxyComponentBus.h>
+#include <AzCore/Console/ILogger.h>
+
+namespace MultiplayerSample
+{
+    void BackgroundMusicComponent::Reflect(AZ::ReflectContext* context)
+    {
+        AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
+        if (serializeContext)
+        {
+            serializeContext->Class<BackgroundMusicComponent, AZ::Component>()
+                ->Field("Shuffle", &BackgroundMusicComponent::m_shuffle)
+                ->Field("Playlist", &BackgroundMusicComponent::m_playlist)
+                ->Version(1);
+
+            AZ::EditContext* editContext = serializeContext->GetEditContext();
+            if (editContext)
+            {
+                editContext->Class<BackgroundMusicComponent>("BackgroundMusicComponent", "Plays a sequence of background music tracks in sequence")
+                    ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+                    ->Attribute(AZ::Edit::Attributes::Category, "MultiplayerSample")
+                    ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &BackgroundMusicComponent::m_shuffle, "Shuffle", "If true, the playlist will be shuffled and play in a randomized ordering")
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &BackgroundMusicComponent::m_playlist, "Playlist", "The set of background music audio triggers to play");
+            }
+        }
+    }
+
+    void BackgroundMusicComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
+    {
+        services.push_back(AZ_CRC_CE("BackgroundMusicComponent"));
+    }
+
+    void BackgroundMusicComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
+    {
+        required.push_back(AZ_CRC("AudioProxyService", 0x7da4c79c));
+    }
+
+    void BackgroundMusicComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services)
+    {
+        services.push_back(AZ_CRC_CE("BackgroundMusicComponent"));
+    }
+
+    void BackgroundMusicComponent::Activate()
+    {
+#if AZ_TRAIT_CLIENT
+        m_audioSystem = AZ::Interface<Audio::IAudioSystem>::Get();
+
+        if (m_shuffle)
+        {
+            // Basic Knuth shuffle
+            for (size_t index = m_playlist.size() - 1; index >= 1; --index)
+            {
+                size_t shuffleElement = rand() % (index + 1);
+                AZStd::swap(m_playlist[index], m_playlist[shuffleElement]);
+            }
+        }
+
+        if (m_audioSystem != nullptr)
+        {
+            m_trackIndex = size_t(-1);
+            ReportTriggerFinished(INVALID_AUDIO_CONTROL_ID);
+        }
+#endif
+
+        Audio::AudioTriggerNotificationBus::Handler::BusConnect(Audio::TriggerNotificationIdType{ GetEntityId() });
+    }
+
+    void BackgroundMusicComponent::Deactivate()
+    {
+        Audio::AudioTriggerNotificationBus::Handler::BusDisconnect(Audio::TriggerNotificationIdType{ GetEntityId() });
+    }
+
+    void BackgroundMusicComponent::ReportTriggerFinished([[maybe_unused]] Audio::TAudioControlID triggerId)
+    {
+        if (m_playlist.empty())
+        {
+            return;
+        }
+
+#if AZ_TRAIT_CLIENT
+        m_trackIndex = ++m_trackIndex % m_playlist.size();
+
+        if (m_audioSystem != nullptr)
+        {
+            const AZStd::string& trackName = m_playlist[m_trackIndex];
+            m_currentTrackTriggerId = m_audioSystem->GetAudioTriggerID(trackName.c_str());
+
+            if (m_currentTrackTriggerId != INVALID_AUDIO_CONTROL_ID)
+            {
+                LmbrCentral::AudioProxyComponentRequestBus::Event(
+                    GetEntityId(),
+                    &LmbrCentral::AudioProxyComponentRequests::ExecuteTrigger,
+                    m_currentTrackTriggerId);
+            }
+        }
+#endif
+    }
+}

+ 42 - 0
Gem/Code/Source/Components/BackgroundMusicComponent.h

@@ -0,0 +1,42 @@
+/*
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Component/Component.h>
+#include <IAudioSystem.h>
+
+namespace MultiplayerSample
+{
+    class BackgroundMusicComponent
+        : public AZ::Component
+        , protected Audio::AudioTriggerNotificationBus::Handler
+    {
+    public:
+        AZ_COMPONENT(MultiplayerSample::BackgroundMusicComponent, "{FA774915-3CDD-4370-B7C9-8F891A006973}");
+
+        static void Reflect(AZ::ReflectContext* context);
+
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+        static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services);
+
+        void Activate() override;
+        void Deactivate() override;
+
+    protected:
+        void ReportTriggerFinished(Audio::TAudioControlID triggerId) override;
+
+    private:
+        size_t m_trackIndex = 0;
+        bool m_shuffle = false;
+        AZStd::vector<AZStd::string> m_playlist;
+        Audio::IAudioSystem* m_audioSystem = nullptr;
+        Audio::TATLIDType m_currentTrackTriggerId = INVALID_AUDIO_CONTROL_ID;
+    };
+}

+ 112 - 18
Gem/Code/Source/Components/Multiplayer/EnergyBallComponent.cpp

@@ -11,16 +11,19 @@
 #include <Multiplayer/Components/NetworkRigidBodyComponent.h>
 #include <MultiplayerSampleTypes.h>
 #include <AzCore/Component/TransformBus.h>
+#include <AzFramework/Physics/Components/SimulatedBodyComponentBus.h>
 #include <AzFramework/Physics/RigidBodyBus.h>
 #include <WeaponNotificationBus.h>
 
 #if AZ_TRAIT_CLIENT
 #   include <PopcornFX/PopcornFXBus.h>
+#   include <DebugDraw/DebugDrawBus.h>
 #endif
 
 namespace MultiplayerSample
 {
     AZ_CVAR(float, sv_EnergyBallImpulseScalar, 500.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "A fudge factor for imparting impulses on rigid bodies due to weapon hits");
+    AZ_CVAR(bool, cl_EnergyBallDebugDraw, false, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "When turned on this will draw the current energy ball location");
 
     void EnergyBallComponent::Reflect(AZ::ReflectContext* context)
     {
@@ -37,27 +40,62 @@ namespace MultiplayerSample
     {
         m_effect = GetExplosionEffect();
         m_effect.Initialize();
+
+#if AZ_TRAIT_CLIENT
+        BallActiveAddEvent(m_ballActiveHandler);
+#endif
     }
 
     void EnergyBallComponent::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
     {
+#if AZ_TRAIT_CLIENT
+        m_ballActiveHandler.Disconnect();
+#endif
     }
 
 #if AZ_TRAIT_CLIENT
-    void EnergyBallComponent::HandleRPC_BallLaunched([[maybe_unused]] AzNetworking::IConnection* invokingConnection, [[maybe_unused]] const AZ::Vector3& location)
+    void EnergyBallComponent::OnBallActiveChanged(bool active)
     {
-        PopcornFX::PopcornFXEmitterComponentRequests* emitterRequests = PopcornFX::PopcornFXEmitterComponentRequestBus::FindFirstHandler(GetEntity()->GetId());
-        if (emitterRequests != nullptr)
+        if (active)
+        {
+            bool startSuccess = false;
+
+            // Set to true to call "Kill" which is deferred, or false to call "Terminate" which is immediate.
+            constexpr bool KillOnRestart = true;
+
+            PopcornFX::PopcornFXEmitterComponentRequestBus::EventResult(startSuccess,
+                GetEntity()->GetId(), &PopcornFX::PopcornFXEmitterComponentRequestBus::Events::Restart, KillOnRestart);
+
+            AZ_Error("EnergyBall", startSuccess, "Restart call for Energy Ball was unsuccessful.");
+
+            if (cl_EnergyBallDebugDraw)
+            {
+                m_debugDrawEvent.Enqueue(AZ::TimeMs{ 0 }, true);
+            }
+        }
+        else
         {
-            emitterRequests->Start();
+            bool killSuccess = false;
+
+            // This would ideally use Kill instead of Terminate, but there is a bug in PopcornFX 2.15.4 that if Kill is
+            // called on the first tick (which can happen), then the effect will get stuck in a permanent waiting-to-die state,
+            // and no amount of Restart calls will ever make it show up again.
+            PopcornFX::PopcornFXEmitterComponentRequestBus::EventResult(killSuccess,
+                GetEntity()->GetId(), &PopcornFX::PopcornFXEmitterComponentRequestBus::Events::Terminate);
+
+            AZ_Error("EnergyBall", killSuccess, "Kill call for Energy Ball was unsuccessful.");
+
+            m_debugDrawEvent.RemoveFromQueue();
         }
     }
 
     void EnergyBallComponent::HandleRPC_BallExplosion([[maybe_unused]] AzNetworking::IConnection* invokingConnection, const HitEvent& hitEvent)
     {
+        // Crate an explosion effect wherever the ball was last at.
         AZ::Transform transform = AZ::Transform::CreateFromQuaternionAndTranslation(AZ::Quaternion::CreateIdentity(), hitEvent.m_target);
         m_effect.TriggerEffect(transform);
 
+        // Notify every entity that was hit that they've received a weapon impact.
         for (const HitEntity& hitEntity : hitEvent.m_hitEntities)
         {
             const AZ::Transform hitTransform = AZ::Transform::CreateLookAt(hitEntity.m_hitPosition, hitEntity.m_hitPosition + hitEntity.m_hitNormal, AZ::Transform::Axis::ZPositive);
@@ -65,11 +103,49 @@ namespace MultiplayerSample
             const AZ::EntityId hitEntityId = handle.Exists() ? handle.GetEntity()->GetId() : AZ::EntityId();
             WeaponNotificationBus::Broadcast(&WeaponNotificationBus::Events::OnWeaponImpact, GetEntity()->GetId(), hitTransform, hitEntityId);
         }
+    }
 
-        PopcornFX::PopcornFXEmitterComponentRequests* emitterRequests = PopcornFX::PopcornFXEmitterComponentRequestBus::FindFirstHandler(GetEntity()->GetId());
-        if (emitterRequests != nullptr)
+    void EnergyBallComponent::DebugDraw()
+    {
+        if (cl_EnergyBallDebugDraw)
         {
-            emitterRequests->Kill();
+            // Each draw only lasts one frame.
+            constexpr float DrawDuration = 0.0f;
+
+            auto* shapeConfig = GetGatherParams().GetCurrentShapeConfiguration();
+            if (shapeConfig->GetShapeType() == Physics::ShapeType::Sphere)
+            {
+                const Physics::SphereShapeConfiguration* sphere = static_cast<const Physics::SphereShapeConfiguration*>(shapeConfig);
+                float debugRadius = sphere->m_radius;
+
+                DebugDraw::DebugDrawRequestBus::Broadcast(
+                    &DebugDraw::DebugDrawRequestBus::Events::DrawSphereAtLocation,
+                    GetEntity()->GetTransform()->GetWorldTM().GetTranslation(),
+                    debugRadius,
+                    AZ::Colors::Green,
+                    DrawDuration
+                );
+            }
+            else if (shapeConfig->GetShapeType() == Physics::ShapeType::Box)
+            {
+                const Physics::BoxShapeConfiguration* box = static_cast<const Physics::BoxShapeConfiguration*>(shapeConfig);
+                AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(
+                    GetEntity()->GetTransform()->GetWorldTM().GetTranslation(),
+                    GetEntity()->GetTransform()->GetWorldTM().GetRotation(),
+                    box->m_dimensions / 2.0f
+                );
+
+                DebugDraw::DebugDrawRequestBus::Broadcast(
+                    &DebugDraw::DebugDrawRequestBus::Events::DrawObb,
+                    obb,
+                    AZ::Colors::Green,
+                    DrawDuration
+                );
+            }
+            else if (shapeConfig->GetShapeType() == Physics::ShapeType::Capsule)
+            {
+                AZ_Error("EnergyBall", false, "Capsule shape type not currently supported with energy ball debug visualization.");
+            }
         }
     }
 #endif
@@ -83,20 +159,29 @@ namespace MultiplayerSample
     void EnergyBallComponentController::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
     {
 #if AZ_TRAIT_SERVER
-        m_collisionCheckEvent.Enqueue(AZ::TimeMs{ 10 }, true);
+        SetBallActive(false);
 #endif
     }
 
     void EnergyBallComponentController::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
     {
 #if AZ_TRAIT_SERVER
-        m_collisionCheckEvent.RemoveFromQueue();
+        SetBallActive(false);
 #endif
     }
 
 #if AZ_TRAIT_SERVER
-    void EnergyBallComponentController::HandleRPC_LaunchBall([[maybe_unused]] AzNetworking::IConnection* invokingConnection, const AZ::Vector3& startingPosition, const AZ::Vector3& direction, const Multiplayer::NetEntityId& owningNetEntityId)
+    void EnergyBallComponentController::HandleRPC_LaunchBall(AzNetworking::IConnection* invokingConnection, const AZ::Vector3& startingPosition, const AZ::Vector3& direction, const Multiplayer::NetEntityId& owningNetEntityId)
     {
+        if (GetBallActive())
+        {
+            return;
+        }
+
+        m_collisionCheckEvent.Enqueue(AZ::TimeMs{ 10 }, true);
+
+        SetBallActive(true);
+
         m_shooterNetEntityId = owningNetEntityId;
         m_hitEvent.m_hitEntities.clear();
 
@@ -106,15 +191,14 @@ namespace MultiplayerSample
         m_direction = direction;
 
         // Move the entity to the start position
-        GetEntity()->GetTransform()->SetWorldTranslation(startingPosition);
+        GetNetworkTransformComponentController()->HandleMultiplayerTeleport(invokingConnection, startingPosition);
 
         // We want to sweep our transform during intersect tests to avoid the ball tunneling through targets
         m_lastSweepTransform = GetEntity()->GetTransform()->GetWorldTM();
 
-        Physics::RigidBodyRequestBus::Event(GetEntityId(), &Physics::RigidBodyRequestBus::Events::EnablePhysics);
+        AzPhysics::SimulatedBodyComponentRequestsBus::Event(GetEntityId(), &AzPhysics::SimulatedBodyComponentRequestsBus::Events::EnablePhysics);
         Physics::RigidBodyRequestBus::Event(GetEntityId(), &Physics::RigidBodyRequestBus::Events::SetLinearVelocity, direction * GetGatherParams().m_travelSpeed);
 
-        RPC_BallLaunched(startingPosition);
     }
 
     void EnergyBallComponentController::HandleRPC_KillBall([[maybe_unused]] AzNetworking::IConnection* invokingConnection)
@@ -124,6 +208,11 @@ namespace MultiplayerSample
 
     void EnergyBallComponentController::CheckForCollisions()
     {
+        if (!GetBallActive())
+        {
+            return;
+        }
+
         const AZ::Vector3& position = GetEntity()->GetTransform()->GetWorldTM().GetTranslation();
         const HitEffect& effect = GetHitEffect();
 
@@ -174,17 +263,22 @@ namespace MultiplayerSample
 
     void EnergyBallComponentController::HideEnergyBall()
     {
+        if (!GetBallActive())
+        {
+            return;
+        }
+
+        SetBallActive(false);
+        m_collisionCheckEvent.RemoveFromQueue();
+
         m_hitEvent.m_target = GetEntity()->GetTransform()->GetWorldTM().GetTranslation();
         m_hitEvent.m_shooterNetEntityId = m_shooterNetEntityId;
         m_hitEvent.m_projectileNetEntityId = GetNetEntityId();
-        RPC_BallExplosion(m_hitEvent);
 
-        Physics::RigidBodyRequestBus::Event(GetEntityId(), &Physics::RigidBodyRequestBus::Events::DisablePhysics);
+        AzPhysics::SimulatedBodyComponentRequestsBus::Event(GetEntityId(), &AzPhysics::SimulatedBodyComponentRequestsBus::Events::DisablePhysics);
         Physics::RigidBodyRequestBus::Event(GetEntityId(), &Physics::RigidBodyRequestBus::Events::SetLinearVelocity, AZ::Vector3::CreateZero());
 
-        // move self and increment resetCount to prevent transform interpolation
-        AZ::TransformBus::Event(GetEntityId(), &AZ::TransformBus::Events::SetWorldTranslation, AZ::Vector3::CreateAxisZ(-1000.f));
-        GetNetworkTransformComponentController()->ModifyResetCount()++;
+        RPC_BallExplosion(m_hitEvent);
     }
 #endif
 }

+ 15 - 1
Gem/Code/Source/Components/Multiplayer/EnergyBallComponent.h

@@ -24,11 +24,25 @@ namespace MultiplayerSample
         void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
 
 #if AZ_TRAIT_CLIENT
-        void HandleRPC_BallLaunched(AzNetworking::IConnection* invokingConnection, const AZ::Vector3& location) override;
         void HandleRPC_BallExplosion(AzNetworking::IConnection* invokingConnection, const HitEvent& hitEvent) override;
 #endif
 
     private:
+#if AZ_TRAIT_CLIENT
+        void DebugDraw();
+        void OnBallActiveChanged(bool active);
+
+        AZ::ScheduledEvent m_debugDrawEvent{ [this]()
+        {
+            DebugDraw();
+        }, AZ::Name("EnergyBallDebugDraw") };
+
+        AZ::Event<bool>::Handler m_ballActiveHandler{ [this](bool active)
+        {
+            OnBallActiveChanged(active);
+        } };
+#endif
+
         GameEffect m_effect;
     };
 

+ 63 - 17
Gem/Code/Source/Effects/GameEffect.cpp

@@ -48,7 +48,10 @@ namespace MultiplayerSample
 #if AZ_TRAIT_CLIENT
         if (m_popcornFx != nullptr)
         {
-            m_popcornFx->DestroyEffect(m_emitter);
+            if (m_popcornFx->IsEffectAlive(m_emitter))
+            {
+                m_popcornFx->DestroyEffect(m_emitter);
+            }
             m_emitter = nullptr;
         }
 
@@ -72,8 +75,11 @@ namespace MultiplayerSample
 
         if (m_popcornFx != nullptr)
         {
-            const PopcornFX::SpawnParams params = PopcornFX::SpawnParams(true, false, AZ::Transform::CreateIdentity());
-            m_emitter = m_popcornFx->SpawnEffectById(m_particleAssetId, params);
+            if (m_particleAssetId.IsValid())
+            {
+                const PopcornFX::SpawnParams params = PopcornFX::SpawnParams(true, false, AZ::Transform::CreateIdentity());
+                m_emitter = m_popcornFx->SpawnEffectById(m_particleAssetId, params);
+            }
         }
 
         if (m_audioSystem != nullptr)
@@ -91,10 +97,18 @@ namespace MultiplayerSample
 #if AZ_TRAIT_CLIENT
         if (m_popcornFx != nullptr)
         {
-            int32_t attrId = m_popcornFx->EffectGetAttributeId(m_emitter, attributeName);
-            if (attrId >= 0)
+            if (m_popcornFx->IsEffectAlive(m_emitter))
+            {
+                int32_t attrId = m_popcornFx->EffectGetAttributeId(m_emitter, attributeName);
+                if (attrId >= 0)
+                {
+                    return m_popcornFx->EffectSetAttributeAsFloat(m_emitter, attrId, value);
+                }
+            }
+            else
             {
-                return m_popcornFx->EffectSetAttributeAsFloat(m_emitter, attrId, value);
+                AZ_Assert(false, "Setting attribute on an emitter that isn't active.");
+                return false;
             }
         }
 #endif
@@ -106,10 +120,18 @@ namespace MultiplayerSample
 #if AZ_TRAIT_CLIENT
         if (m_popcornFx != nullptr)
         {
-            int32_t attrId = m_popcornFx->EffectGetAttributeId(m_emitter, attributeName);
-            if (attrId >= 0)
+            if (m_popcornFx->IsEffectAlive(m_emitter))
             {
-                return m_popcornFx->EffectSetAttributeAsFloat2(m_emitter, attrId, value);
+                int32_t attrId = m_popcornFx->EffectGetAttributeId(m_emitter, attributeName);
+                if (attrId >= 0)
+                {
+                    return m_popcornFx->EffectSetAttributeAsFloat2(m_emitter, attrId, value);
+                }
+            }
+            else
+            {
+                AZ_Assert(false, "Setting attribute on an emitter that isn't active.");
+                return false;
             }
         }
 #endif
@@ -121,10 +143,18 @@ namespace MultiplayerSample
 #if AZ_TRAIT_CLIENT
         if (m_popcornFx != nullptr)
         {
-            int32_t attrId = m_popcornFx->EffectGetAttributeId(m_emitter, attributeName);
-            if (attrId >= 0)
+            if (m_popcornFx->IsEffectAlive(m_emitter))
+            {
+                int32_t attrId = m_popcornFx->EffectGetAttributeId(m_emitter, attributeName);
+                if (attrId >= 0)
+                {
+                    return m_popcornFx->EffectSetAttributeAsFloat3(m_emitter, attrId, value);
+                }
+            }
+            else
             {
-                return m_popcornFx->EffectSetAttributeAsFloat3(m_emitter, attrId, value);
+                AZ_Assert(false, "Setting attribute on an emitter that isn't active.");
+                return false;
             }
         }
 #endif
@@ -136,10 +166,18 @@ namespace MultiplayerSample
 #if AZ_TRAIT_CLIENT
         if (m_popcornFx != nullptr)
         {
-            int32_t attrId = m_popcornFx->EffectGetAttributeId(m_emitter, attributeName);
-            if (attrId >= 0)
+            if (m_popcornFx->IsEffectAlive(m_emitter))
+            {
+                int32_t attrId = m_popcornFx->EffectGetAttributeId(m_emitter, attributeName);
+                if (attrId >= 0)
+                {
+                    return m_popcornFx->EffectSetAttributeAsFloat4(m_emitter, attrId, value);
+                }
+            }
+            else
             {
-                return m_popcornFx->EffectSetAttributeAsFloat4(m_emitter, attrId, value);
+                AZ_Assert(false, "Setting attribute on an emitter that isn't active.");
+                return false;
             }
         }
 #endif
@@ -156,8 +194,16 @@ namespace MultiplayerSample
         {
             if (PopcornFX::PopcornFXRequests* popcornFx = PopcornFX::PopcornFXRequestBus::FindFirstHandler())
             {
-                popcornFx->EffectSetTransform(m_emitter, transformOffset);
-                popcornFx->EffectRestart(m_emitter, cl_KillEffectOnRestart);
+                if (m_popcornFx->IsEffectAlive(m_emitter))
+                {
+                    popcornFx->EffectSetTransform(m_emitter, transformOffset);
+                    popcornFx->EffectSetTeleportThisFrame(m_emitter);
+                    popcornFx->EffectRestart(m_emitter, cl_KillEffectOnRestart);
+                }
+                else
+                {
+                    AZ_Assert(false, "Triggering an inactive emitter.");
+                }
             }
         }
 

+ 10 - 9
Gem/Code/Source/MultiplayerSampleModule.cpp

@@ -13,19 +13,19 @@
 #include <Components/UI/UiCoinCountComponent.h>
 #include <Components/UI/UiGameOverComponent.h>
 #include <Components/UI/UiPlayerArmorComponent.h>
+#include <Components/BackgroundMusicComponent.h>
 #include <Components/ScriptableDecalComponent.h>
-#if AZ_TRAIT_CLIENT
-    #include <Components/UI/HUDComponent.h>
-    #include <Components/UI/UiMatchPlayerCoinCountsComponent.h>
-    #include <Components/UI/UiRestBetweenRoundsComponent.h>
-    #include <Components/UI/UiSettingsComponent.h>
-    #include <Components/UI/UiStartMenuComponent.h>
-#endif
-
 #include <Source/AutoGen/AutoComponentTypes.h>
-
 #include "MultiplayerSampleSystemComponent.h"
 
+#if AZ_TRAIT_CLIENT
+#   include <Components/UI/HUDComponent.h>
+#   include <Components/UI/UiMatchPlayerCoinCountsComponent.h>
+#   include <Components/UI/UiRestBetweenRoundsComponent.h>
+#   include <Components/UI/UiSettingsComponent.h>
+#   include <Components/UI/UiStartMenuComponent.h>
+#endif
+
 namespace MultiplayerSample
 {
     class MultiplayerSampleModule
@@ -45,6 +45,7 @@ namespace MultiplayerSample
                 ExampleFilteredEntityComponent::CreateDescriptor(),
                 NetworkPrefabSpawnerComponent::CreateDescriptor(),
                 UiCoinCountComponent::CreateDescriptor(),
+                BackgroundMusicComponent::CreateDescriptor(),
                 ScriptableDecalComponent::CreateDescriptor(),
                 #if AZ_TRAIT_CLIENT
                     HUDComponent::CreateDescriptor(),

+ 3 - 0
Gem/Code/multiplayersample_files.cmake

@@ -73,6 +73,9 @@ set(FILES
     Source/Components/Multiplayer/EnergyCannonComponent.cpp
     Source/Components/Multiplayer/EnergyCannonComponent.h
 
+    Source/Components/BackgroundMusicComponent.cpp
+    Source/Components/BackgroundMusicComponent.h
+
     Source/Components/RpcTesterComponent.cpp
     Source/Components/RpcTesterComponent.h
     

+ 52 - 9
Levels/NewStarbase/NewStarbase.prefab

@@ -2535,6 +2535,11 @@
                     "$type": "EditorPendingCompositionComponent",
                     "Id": 16817453197198982078
                 },
+                "Component_[2619917249643206097]": {
+                    "$type": "EditorCommentComponent",
+                    "Id": 2619917249643206097,
+                    "Configuration": "For more information about lighting please see the level design guide in the multiplayersample documentation folder."
+                },
                 "Component_[376094705505411548]": {
                     "$type": "EditorEntitySortComponent",
                     "Id": 376094705505411548,
@@ -4487,6 +4492,11 @@
                     "Id": 7186247374812053450,
                     "Parent Entity": "Entity_[60274689909647]"
                 },
+                "Component_[7963844296059785842]": {
+                    "$type": "EditorCommentComponent",
+                    "Id": 7963844296059785842,
+                    "Configuration": "This is a simple 1x1 tile terrain. The spawners operate within the bounds of the box for the terrain spawner. The child entity height is an image gradient signal that loads a height map asset to generate the height map, which is then sampled by the parent terrain entity, via the terrain height gradient list component. The matching macro color map and macro normal map are loaded in the terrain macro material component."
+                },
                 "Component_[9388349147874105140]": {
                     "$type": "EditorTerrainLayerSpawnerComponent",
                     "Id": 9388349147874105140
@@ -7097,6 +7107,11 @@
                     "$type": "EditorInspectorComponent",
                     "Id": 17057238313917441482
                 },
+                "Component_[17703777834056015433]": {
+                    "$type": "EditorCommentComponent",
+                    "Id": 17703777834056015433,
+                    "Configuration": "This is currently not contributing to global illumination. This is where we would add one or more reflection probes to bake reflections for the level geometry."
+                },
                 "Component_[2149849594454303666]": {
                     "$type": "EditorOnlyEntityComponent",
                     "Id": 2149849594454303666
@@ -8528,6 +8543,11 @@
                     "$type": "EditorDisabledCompositionComponent",
                     "Id": 15744299950611104828
                 },
+                "Component_[1684972590650734165]": {
+                    "$type": "EditorCommentComponent",
+                    "Id": 1684972590650734165,
+                    "Configuration": "The sun properties of the sky atmosphere contain a  reference to the child sun entity. The transform of the child sun entity determines the position of the sun in the sky atmoshpere. The sky atmosphere is baked into the image-based lighting that is loaded into the Global illlumination sample's lighting information from the sky light, the sky atmosphere and the sun entity."
+                },
                 "Component_[1728065122520318572]": {
                     "$type": "EditorLockComponent",
                     "Id": 1728065122520318572
@@ -11239,6 +11259,11 @@
                     "$type": "EditorEntityIconComponent",
                     "Id": 11895140916889160460
                 },
+                "Component_[13025475667675684062]": {
+                    "$type": "EditorCommentComponent",
+                    "Id": 13025475667675684062,
+                    "Configuration": "This 3rd person spring-arm camera is controlled by each client's player."
+                },
                 "Component_[16880285896855930892]": {
                     "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
                     "Id": 16880285896855930892,
@@ -11246,7 +11271,7 @@
                         "Configuration": {
                             "Field of View": 55.0,
                             "Far Clip Plane Distance": 4096.0,
-                            "EditorEntityId": 10557690388680515673
+                            "EditorEntityId": 17729197467549002539
                         }
                     }
                 },
@@ -11577,6 +11602,19 @@
                     "$type": "EditorEntitySortComponent",
                     "Id": 14774980749977237053
                 },
+                "Component_[14919200452665967980]": {
+                    "$type": "GenericComponentWrapper",
+                    "Id": 14919200452665967980,
+                    "m_template": {
+                        "$type": "MultiplayerSample::BackgroundMusicComponent",
+                        "Shuffle": true,
+                        "Playlist": [
+                            "rocket",
+                            "beauty_flow",
+                            "future_gladiator"
+                        ]
+                    }
+                },
                 "Component_[17049943556665966323]": {
                     "$type": "EditorEntityIconComponent",
                     "Id": 17049943556665966323
@@ -11613,6 +11651,11 @@
                     "$type": "EditorPendingCompositionComponent",
                     "Id": 612576140938853376
                 },
+                "Component_[7829044378931254902]": {
+                    "$type": "EditorCommentComponent",
+                    "Id": 7829044378931254902,
+                    "Configuration": "Global ambient \"background\" audio for the level is hooked up here. Individual prefabs may have their own ambient sounds."
+                },
                 "Component_[9778753844251016872]": {
                     "$type": "EditorBoxShapeComponent",
                     "Id": 9778753844251016872
@@ -30814,7 +30857,7 @@
                 {
                     "op": "replace",
                     "path": "/ContainerEntity/Components/Component_[2563122736071885678]/Transform Data/Rotate/1",
-                    "value": 1.2738307587564779e-12
+                    "value": 1.273830758756478e-12
                 },
                 {
                     "op": "replace",
@@ -30854,7 +30897,7 @@
                 {
                     "op": "replace",
                     "path": "/ContainerEntity/Components/Component_[2563122736071885678]/Transform Data/Rotate/1",
-                    "value": 1.2738307587564779e-12
+                    "value": 1.273830758756478e-12
                 },
                 {
                     "op": "replace",
@@ -30894,7 +30937,7 @@
                 {
                     "op": "replace",
                     "path": "/ContainerEntity/Components/Component_[2563122736071885678]/Transform Data/Rotate/1",
-                    "value": 1.2738307587564779e-12
+                    "value": 1.273830758756478e-12
                 },
                 {
                     "op": "replace",
@@ -30934,7 +30977,7 @@
                 {
                     "op": "replace",
                     "path": "/ContainerEntity/Components/Component_[2563122736071885678]/Transform Data/Rotate/1",
-                    "value": 1.2738307587564779e-12
+                    "value": 1.273830758756478e-12
                 },
                 {
                     "op": "replace",
@@ -30974,7 +31017,7 @@
                 {
                     "op": "replace",
                     "path": "/ContainerEntity/Components/Component_[2563122736071885678]/Transform Data/Rotate/1",
-                    "value": 1.2738307587564779e-12
+                    "value": 1.273830758756478e-12
                 },
                 {
                     "op": "replace",
@@ -31014,7 +31057,7 @@
                 {
                     "op": "replace",
                     "path": "/ContainerEntity/Components/Component_[2563122736071885678]/Transform Data/Rotate/1",
-                    "value": 1.2738307587564779e-12
+                    "value": 1.273830758756478e-12
                 },
                 {
                     "op": "replace",
@@ -31054,7 +31097,7 @@
                 {
                     "op": "replace",
                     "path": "/ContainerEntity/Components/Component_[2563122736071885678]/Transform Data/Rotate/1",
-                    "value": 1.2738307587564779e-12
+                    "value": 1.273830758756478e-12
                 },
                 {
                     "op": "replace",
@@ -31094,7 +31137,7 @@
                 {
                     "op": "replace",
                     "path": "/ContainerEntity/Components/Component_[2563122736071885678]/Transform Data/Rotate/1",
-                    "value": 1.2738307587564779e-12
+                    "value": 1.273830758756478e-12
                 },
                 {
                     "op": "replace",

+ 6 - 7
Registry/settings.multiplayersample_gamelauncher.setreg

@@ -1,11 +1,10 @@
 {
-    "Amazon": {
-        "AzCore": {
-            "Runtime": {
-                "ConsoleCommands": {
-                    "cl_serverAddr": "127.0.0.1",
-                    "loadlevel": "startmenu"
-                }
+    "O3DE": {
+       "Autoexec": {
+            "ConsoleCommands": {
+                "r_displayInfo": 0,
+                "cl_serverAddr": "127.0.0.1",
+                "loadlevel": "startmenu"
             }
         }
     }

+ 6 - 7
Registry/settings.multiplayersample_unifiedlauncher.setreg

@@ -1,11 +1,10 @@
 {
-    "Amazon": {
-        "AzCore": {
-            "Runtime": {
-                "ConsoleCommands": {
-                    "cl_serverAddr": "127.0.0.1",
-                    "loadlevel": "startmenu"
-                }
+    "O3DE": {
+       "Autoexec": {
+            "ConsoleCommands": {
+                "r_displayInfo": 0,
+                "cl_serverAddr": "127.0.0.1",
+                "loadlevel": "newstarbase"
             }
         }
     }

+ 3 - 0
Sounds/wwise/1070395499.wem

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:45a644501a6762f30e5b7cef444f41bcc312d09f91398301dbd9e08d8671e87d
+size 66539584

+ 3 - 0
Sounds/wwise/1073420800.wem

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b1deeee7019c3eff5673cac9920dedef11f0feadf1553392a51628d5c1045ae0
+size 38283328

+ 3 - 0
Sounds/wwise/115250578.wem

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:708537b00f9a619c957a89d9c038512d169fe5301ebfe124515c1b14354b360b
+size 25924672

+ 3 - 0
Sounds/wwise/655023540.wem

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a1c4fe8e4e9c51054324c524ad049baa94774d56f9a9a1d5faf10bbcaa91417e
+size 76451392

+ 2 - 2
Sounds/wwise/MultiplayerSample_SoundBank.bnk

@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:e26efb95f47ba277d16fec0b7ce36c9b04ebcd836ace81782c64a13b9419f7de
-size 63086512
+oid sha256:21b03265f9118a1ea525635bf2663d100a947f5cb2795d0982d2ab9fbab73c47
+size 63087131

+ 192 - 0
Sounds/wwise_project/Actor-Mixer Hierarchy/AMPS/LVL.wwu

@@ -82,6 +82,198 @@
 									</ChildrenList>
 									<ObjectLists/>
 								</BlendContainer>
+								<ActorMixer Name="beauty_flow" ID="{9EC966BE-D68B-4A2D-A56C-4892CE97A77D}" ShortID="215290428">
+									<PropertyList>
+										<Property Name="3DSpatialization" Type="int16" Value="2"/>
+										<Property Name="BelowThresholdBehavior" Type="int16" Value="3"/>
+										<Property Name="PriorityDistanceFactor" Type="bool" Value="True"/>
+										<Property Name="UserAuxSendVolume0" Type="Real64">
+											<ValueList>
+												<Value>-3</Value>
+											</ValueList>
+										</Property>
+									</PropertyList>
+									<ReferenceList>
+										<Reference Name="Attenuation">
+											<ObjectRef Name="ATN_Default_20" ID="{9A356296-FB49-4226-8845-131AFAB59884}" WorkUnitID="{FF701137-ABB4-4FD9-800E-7C2F77E85689}"/>
+										</Reference>
+										<Reference Name="Conversion">
+											<ObjectRef Name="Default Conversion Settings" ID="{6D1B890C-9826-4384-BF07-C15223E9FB56}" WorkUnitID="{0119FCBC-B171-4B2F-BB85-593A23CC9CD0}"/>
+										</Reference>
+										<Reference Name="OutputBus">
+											<ObjectRef Name="SX" ID="{9BAD8B54-940E-473A-9DE7-E613A4F0BB4B}" WorkUnitID="{8B26C89C-CDEC-42FD-AE82-2A0A21AD7AAE}"/>
+										</Reference>
+										<Reference Name="UserAuxSend0">
+											<ObjectRef Name="RVB_EXT_Main" ID="{F8DF5907-D7A9-43AF-B130-2AB20EED85E3}" WorkUnitID="{8B26C89C-CDEC-42FD-AE82-2A0A21AD7AAE}"/>
+										</Reference>
+									</ReferenceList>
+									<ChildrenList>
+										<Sound Name="Beauty Flow" ID="{ECDF9185-197D-4EAD-BF3B-F3EAE8040A1E}" ShortID="1058521084">
+											<PropertyList>
+												<Property Name="IsStreamingEnabled" Type="bool">
+													<ValueList>
+														<Value>True</Value>
+													</ValueList>
+												</Property>
+												<Property Name="Volume" Type="Real64">
+													<ValueList>
+														<Value>-6</Value>
+													</ValueList>
+												</Property>
+											</PropertyList>
+											<ReferenceList>
+												<Reference Name="Conversion">
+													<ObjectRef Name="Default Conversion Settings" ID="{6D1B890C-9826-4384-BF07-C15223E9FB56}" WorkUnitID="{0119FCBC-B171-4B2F-BB85-593A23CC9CD0}"/>
+												</Reference>
+												<Reference Name="OutputBus">
+													<ObjectRef Name="Master Audio Bus" ID="{1514A4D8-1DA6-412A-A17E-75CA0C2149F3}" WorkUnitID="{F62C277B-2C60-43BB-A8B2-F1E94C3F98EC}"/>
+												</Reference>
+											</ReferenceList>
+											<ChildrenList>
+												<AudioFileSource Name="Beauty Flow" ID="{A46E9731-E1EB-42EE-BE7F-F6437FDF809C}">
+													<Language>SFX</Language>
+													<AudioFile>Beauty Flow.wav</AudioFile>
+													<MediaIDList>
+														<MediaID ID="655023540"/>
+													</MediaIDList>
+												</AudioFileSource>
+											</ChildrenList>
+											<ObjectLists/>
+											<ActiveSourceList>
+												<ActiveSource Name="Beauty Flow" ID="{A46E9731-E1EB-42EE-BE7F-F6437FDF809C}" Platform="Linked"/>
+											</ActiveSourceList>
+										</Sound>
+									</ChildrenList>
+									<ObjectLists/>
+								</ActorMixer>
+								<ActorMixer Name="future_gladiator" ID="{AAAFDCA3-E9CD-4C2A-8E30-8538B7B78B31}" ShortID="48597">
+									<PropertyList>
+										<Property Name="3DSpatialization" Type="int16" Value="2"/>
+										<Property Name="BelowThresholdBehavior" Type="int16" Value="3"/>
+										<Property Name="PriorityDistanceFactor" Type="bool" Value="True"/>
+										<Property Name="UserAuxSendVolume0" Type="Real64">
+											<ValueList>
+												<Value>-3</Value>
+											</ValueList>
+										</Property>
+									</PropertyList>
+									<ReferenceList>
+										<Reference Name="Attenuation">
+											<ObjectRef Name="ATN_Default_20" ID="{9A356296-FB49-4226-8845-131AFAB59884}" WorkUnitID="{FF701137-ABB4-4FD9-800E-7C2F77E85689}"/>
+										</Reference>
+										<Reference Name="Conversion">
+											<ObjectRef Name="Default Conversion Settings" ID="{6D1B890C-9826-4384-BF07-C15223E9FB56}" WorkUnitID="{0119FCBC-B171-4B2F-BB85-593A23CC9CD0}"/>
+										</Reference>
+										<Reference Name="OutputBus">
+											<ObjectRef Name="SX" ID="{9BAD8B54-940E-473A-9DE7-E613A4F0BB4B}" WorkUnitID="{8B26C89C-CDEC-42FD-AE82-2A0A21AD7AAE}"/>
+										</Reference>
+										<Reference Name="UserAuxSend0">
+											<ObjectRef Name="RVB_EXT_Main" ID="{F8DF5907-D7A9-43AF-B130-2AB20EED85E3}" WorkUnitID="{8B26C89C-CDEC-42FD-AE82-2A0A21AD7AAE}"/>
+										</Reference>
+									</ReferenceList>
+									<ChildrenList>
+										<Sound Name="Future Gladiator" ID="{2C0BD4CA-76EC-4714-9C88-C5364FD4361D}" ShortID="722579746">
+											<PropertyList>
+												<Property Name="IsStreamingEnabled" Type="bool">
+													<ValueList>
+														<Value>True</Value>
+													</ValueList>
+												</Property>
+												<Property Name="Volume" Type="Real64">
+													<ValueList>
+														<Value>-8</Value>
+													</ValueList>
+												</Property>
+											</PropertyList>
+											<ReferenceList>
+												<Reference Name="Conversion">
+													<ObjectRef Name="Default Conversion Settings" ID="{6D1B890C-9826-4384-BF07-C15223E9FB56}" WorkUnitID="{0119FCBC-B171-4B2F-BB85-593A23CC9CD0}"/>
+												</Reference>
+												<Reference Name="OutputBus">
+													<ObjectRef Name="Master Audio Bus" ID="{1514A4D8-1DA6-412A-A17E-75CA0C2149F3}" WorkUnitID="{F62C277B-2C60-43BB-A8B2-F1E94C3F98EC}"/>
+												</Reference>
+											</ReferenceList>
+											<ChildrenList>
+												<AudioFileSource Name="Future Gladiator" ID="{4FD3E458-FA8C-4F43-9523-66364BF7511F}">
+													<Language>SFX</Language>
+													<AudioFile>Future Gladiator.wav</AudioFile>
+													<MediaIDList>
+														<MediaID ID="1073420800"/>
+													</MediaIDList>
+												</AudioFileSource>
+											</ChildrenList>
+											<ObjectLists/>
+											<ActiveSourceList>
+												<ActiveSource Name="Future Gladiator" ID="{4FD3E458-FA8C-4F43-9523-66364BF7511F}" Platform="Linked"/>
+											</ActiveSourceList>
+										</Sound>
+									</ChildrenList>
+									<ObjectLists/>
+								</ActorMixer>
+								<ActorMixer Name="rocket" ID="{4D1305BD-E28A-49F1-8E91-D75EB6EA59FB}" ShortID="143389107">
+									<PropertyList>
+										<Property Name="3DSpatialization" Type="int16" Value="2"/>
+										<Property Name="BelowThresholdBehavior" Type="int16" Value="3"/>
+										<Property Name="PriorityDistanceFactor" Type="bool" Value="True"/>
+										<Property Name="UserAuxSendVolume0" Type="Real64">
+											<ValueList>
+												<Value>-3</Value>
+											</ValueList>
+										</Property>
+									</PropertyList>
+									<ReferenceList>
+										<Reference Name="Attenuation">
+											<ObjectRef Name="ATN_Default_20" ID="{9A356296-FB49-4226-8845-131AFAB59884}" WorkUnitID="{FF701137-ABB4-4FD9-800E-7C2F77E85689}"/>
+										</Reference>
+										<Reference Name="Conversion">
+											<ObjectRef Name="Default Conversion Settings" ID="{6D1B890C-9826-4384-BF07-C15223E9FB56}" WorkUnitID="{0119FCBC-B171-4B2F-BB85-593A23CC9CD0}"/>
+										</Reference>
+										<Reference Name="OutputBus">
+											<ObjectRef Name="SX" ID="{9BAD8B54-940E-473A-9DE7-E613A4F0BB4B}" WorkUnitID="{8B26C89C-CDEC-42FD-AE82-2A0A21AD7AAE}"/>
+										</Reference>
+										<Reference Name="UserAuxSend0">
+											<ObjectRef Name="RVB_EXT_Main" ID="{F8DF5907-D7A9-43AF-B130-2AB20EED85E3}" WorkUnitID="{8B26C89C-CDEC-42FD-AE82-2A0A21AD7AAE}"/>
+										</Reference>
+									</ReferenceList>
+									<ChildrenList>
+										<Sound Name="Rocket" ID="{E8258E1E-BB45-4281-9C81-3174071BEEB0}" ShortID="758395372">
+											<PropertyList>
+												<Property Name="IsStreamingEnabled" Type="bool">
+													<ValueList>
+														<Value>True</Value>
+													</ValueList>
+												</Property>
+												<Property Name="Volume" Type="Real64">
+													<ValueList>
+														<Value>-8</Value>
+													</ValueList>
+												</Property>
+											</PropertyList>
+											<ReferenceList>
+												<Reference Name="Conversion">
+													<ObjectRef Name="Default Conversion Settings" ID="{6D1B890C-9826-4384-BF07-C15223E9FB56}" WorkUnitID="{0119FCBC-B171-4B2F-BB85-593A23CC9CD0}"/>
+												</Reference>
+												<Reference Name="OutputBus">
+													<ObjectRef Name="Master Audio Bus" ID="{1514A4D8-1DA6-412A-A17E-75CA0C2149F3}" WorkUnitID="{F62C277B-2C60-43BB-A8B2-F1E94C3F98EC}"/>
+												</Reference>
+											</ReferenceList>
+											<ChildrenList>
+												<AudioFileSource Name="Rocket" ID="{3057E892-DA3F-4CB0-8A81-73AF30B052BD}">
+													<Language>SFX</Language>
+													<AudioFile>Rocket.wav</AudioFile>
+													<MediaIDList>
+														<MediaID ID="115250578"/>
+													</MediaIDList>
+												</AudioFileSource>
+											</ChildrenList>
+											<ObjectLists/>
+											<ActiveSourceList>
+												<ActiveSource Name="Rocket" ID="{3057E892-DA3F-4CB0-8A81-73AF30B052BD}" Platform="Linked"/>
+											</ActiveSourceList>
+										</Sound>
+									</ChildrenList>
+									<ObjectLists/>
+								</ActorMixer>
 							</ChildrenList>
 							<ObjectLists/>
 						</ActorMixer>

+ 14 - 0
Sounds/wwise_project/Actor-Mixer Hierarchy/AMPS/MX.wwu

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<WwiseDocument Type="WorkUnit" ID="{AA20B5BC-06AE-4EC5-A248-109D9EE35897}" SchemaVersion="103">
+	<AudioObjects>
+		<WorkUnit Name="MX" ID="{AA20B5BC-06AE-4EC5-A248-109D9EE35897}" PersistMode="Standalone">
+			<PropertyList>
+				<Property Name="Inclusion" Type="bool">
+					<ValueList>
+						<Value>False</Value>
+					</ValueList>
+				</Property>
+			</PropertyList>
+		</WorkUnit>
+	</AudioObjects>
+</WwiseDocument>

+ 63 - 3
Sounds/wwise_project/Events/AMPS/AMB.wwu

@@ -6,9 +6,6 @@
 				<Event Name="play_sx_amb_ext_general" ID="{118E75AA-7412-45A0-AAA9-52CD47DB9E41}">
 					<ChildrenList>
 						<Action Name="" ID="{E12EFB24-AB65-4232-BD67-8F6925C157F0}" ShortID="745775555">
-							<PropertyList>
-								<Property Name="FadeTime" Type="Real64" Value="0.3"/>
-							</PropertyList>
 							<ReferenceList>
 								<Reference Name="Target">
 									<ObjectRef Name="sx_amb_ext_generalWindLoop" ID="{F55CE3A4-96C3-4E54-8267-FBB6A47AAAE1}" WorkUnitID="{FF882DA0-D34E-47CD-9819-576540D5FB1C}"/>
@@ -56,6 +53,69 @@
 						</Action>
 					</ChildrenList>
 				</Event>
+				<Event Name="rocket" ID="{4060BEF8-E908-4BDE-AFD2-6E0FA057CD6B}">
+					<ChildrenList>
+						<Action Name="" ID="{13665353-3628-4162-B258-14BA5D07D49B}" ShortID="800090568">
+							<ReferenceList>
+								<Reference Name="Target">
+									<ObjectRef Name="Rocket" ID="{E8258E1E-BB45-4281-9C81-3174071BEEB0}" WorkUnitID="{FF882DA0-D34E-47CD-9819-576540D5FB1C}"/>
+								</Reference>
+							</ReferenceList>
+						</Action>
+						<Action Name="" ID="{6606CDFB-B3CA-40FA-B69C-FBFB4A2DBAFA}" ShortID="608537304">
+							<PropertyList>
+								<Property Name="ActionType" Type="int16" Value="36"/>
+							</PropertyList>
+							<ReferenceList>
+								<Reference Name="Target">
+									<ObjectRef Name="Rocket" ID="{E8258E1E-BB45-4281-9C81-3174071BEEB0}" WorkUnitID="{FF882DA0-D34E-47CD-9819-576540D5FB1C}"/>
+								</Reference>
+							</ReferenceList>
+						</Action>
+					</ChildrenList>
+				</Event>
+				<Event Name="future_gladiator" ID="{A437974A-51F1-4F3C-B623-6D17741CE162}">
+					<ChildrenList>
+						<Action Name="" ID="{54954584-C040-4E0F-A066-CF784DD6C169}" ShortID="1070131939">
+							<ReferenceList>
+								<Reference Name="Target">
+									<ObjectRef Name="Future Gladiator" ID="{2C0BD4CA-76EC-4714-9C88-C5364FD4361D}" WorkUnitID="{FF882DA0-D34E-47CD-9819-576540D5FB1C}"/>
+								</Reference>
+							</ReferenceList>
+						</Action>
+						<Action Name="" ID="{DB91EEB9-C99B-4004-9B5E-8BA71D82F265}" ShortID="285746269">
+							<PropertyList>
+								<Property Name="ActionType" Type="int16" Value="36"/>
+							</PropertyList>
+							<ReferenceList>
+								<Reference Name="Target">
+									<ObjectRef Name="Future Gladiator" ID="{2C0BD4CA-76EC-4714-9C88-C5364FD4361D}" WorkUnitID="{FF882DA0-D34E-47CD-9819-576540D5FB1C}"/>
+								</Reference>
+							</ReferenceList>
+						</Action>
+					</ChildrenList>
+				</Event>
+				<Event Name="beauty_flow" ID="{E24D72A5-1DCD-4C84-BA05-4D6ACA979ABC}">
+					<ChildrenList>
+						<Action Name="" ID="{67ECBB5C-B496-4BEF-80DC-C0BEDF31792E}" ShortID="780551046">
+							<ReferenceList>
+								<Reference Name="Target">
+									<ObjectRef Name="Beauty Flow" ID="{ECDF9185-197D-4EAD-BF3B-F3EAE8040A1E}" WorkUnitID="{FF882DA0-D34E-47CD-9819-576540D5FB1C}"/>
+								</Reference>
+							</ReferenceList>
+						</Action>
+						<Action Name="" ID="{2861746A-0B52-4070-87C9-45AE8E611975}" ShortID="163506992">
+							<PropertyList>
+								<Property Name="ActionType" Type="int16" Value="36"/>
+							</PropertyList>
+							<ReferenceList>
+								<Reference Name="Target">
+									<ObjectRef Name="Beauty Flow" ID="{ECDF9185-197D-4EAD-BF3B-F3EAE8040A1E}" WorkUnitID="{FF882DA0-D34E-47CD-9819-576540D5FB1C}"/>
+								</Reference>
+							</ReferenceList>
+						</Action>
+					</ChildrenList>
+				</Event>
 			</ChildrenList>
 		</WorkUnit>
 	</Events>

+ 11 - 1
Sounds/wwise_project/Events/Default O3DE Work Unit.wwu

@@ -67,7 +67,17 @@
 						</Action>
 					</ChildrenList>
 				</Event>
-				<Event Name="do_nothing" ID="{59644E92-2831-425C-ACD3-BF068AAE1F77}"/>
+				<Event Name="do_nothing" ID="{59644E92-2831-425C-ACD3-BF068AAE1F77}">
+					<ChildrenList>
+						<Action Name="" ID="{4599C36D-7735-41D4-B8C6-07C717506577}" ShortID="473161540"/>
+						<Action Name="" ID="{EA54B31A-9789-475C-B3D1-6BC334158C87}" ShortID="599963739">
+							<PropertyList>
+								<Property Name="ActionType" Type="int16" Value="36"/>
+							</PropertyList>
+							<ReferenceList/>
+						</Action>
+					</ChildrenList>
+				</Event>
 			</ChildrenList>
 		</WorkUnit>
 	</Events>

+ 3 - 0
Sounds/wwise_project/Originals/SFX/Beauty Flow.wav

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d62776f0e41ac60ad50bd82ac85c3c67b2eec5acc39cfdcdb0025a736c88c2d3
+size 76451506

+ 3 - 0
Sounds/wwise_project/Originals/SFX/Future Gladiator.wav

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:108c7168890b9bbd8b9fdac8fa66e5d85104f3b282d55c64babcaf07f2257890
+size 38283466

+ 3 - 0
Sounds/wwise_project/Originals/SFX/Rocket.wav

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:40c9d5fe79bfc3fdf40e98993b0a981c6dcad3a955af5af761a7f79c95a1fe25
+size 25924766

+ 3 - 0
Sounds/wwise_project/Originals/SFX/incompetech/Dream Catcher.wav

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3b48ae6dfc6ba1f35f5ca0fe3ffcdd2fbd768cb53bb4c3c6ec289a4bf65c4686
+size 66539678

+ 12 - 0
Sounds/wwise_project/Soundcaster Sessions/Default Work Unit.wwu

@@ -17,6 +17,10 @@
 							<ObjectRef Name="play_sx_int_defenseturret_projectile" ID="{445FBCD9-FCA2-41BE-B2E0-FF4E640AAC7B}" WorkUnitID="{CF19DCBF-DBAF-47EA-BB92-20770380FC6C}"/>
 							<Position X="0" Y="4"/>
 						</Module>
+						<Module>
+							<ObjectRef Name="beauty_flow" ID="{E24D72A5-1DCD-4C84-BA05-4D6ACA979ABC}" WorkUnitID="{DE9FC369-2076-4F07-9C00-6203DBF0184F}"/>
+							<Position X="0" Y="5"/>
+						</Module>
 						<Module>
 							<ObjectRef Name="play_sx_int_malfunctioningshieldgenerator_explo" ID="{A910A681-E6E6-47EF-9061-B9753C009A61}" WorkUnitID="{D49A7F17-5E56-4DE2-816D-4286ED6A3BE2}"/>
 							<Position X="1" Y="0"/>
@@ -29,6 +33,10 @@
 							<ObjectRef Name="stop_sx_int_defenseturret_projectile" ID="{ADF03BF2-DAFD-4FA1-BAC6-6CEC22FD0EFD}" WorkUnitID="{CF19DCBF-DBAF-47EA-BB92-20770380FC6C}"/>
 							<Position X="1" Y="4"/>
 						</Module>
+						<Module>
+							<ObjectRef Name="future_gladiator" ID="{A437974A-51F1-4F3C-B623-6D17741CE162}" WorkUnitID="{DE9FC369-2076-4F07-9C00-6203DBF0184F}"/>
+							<Position X="1" Y="5"/>
+						</Module>
 						<Module>
 							<ObjectRef Name="play_sx_player_footstep" ID="{1FFADD80-2B41-4080-BCCC-C50E8E9F54A4}" WorkUnitID="{6146481B-5849-48AD-9DBA-B2D263C55E44}"/>
 							<Position X="2" Y="1"/>
@@ -41,6 +49,10 @@
 							<ObjectRef Name="play_sx_wpn_laserpistol_fire" ID="{FA50B607-E2A8-4E18-B8FC-632C1F353C41}" WorkUnitID="{127FA651-B259-4F86-BC4D-A900F3A4CCA2}"/>
 							<Position X="2" Y="3"/>
 						</Module>
+						<Module>
+							<ObjectRef Name="rocket" ID="{4060BEF8-E908-4BDE-AFD2-6E0FA057CD6B}" WorkUnitID="{DE9FC369-2076-4F07-9C00-6203DBF0184F}"/>
+							<Position X="2" Y="5"/>
+						</Module>
 						<Module>
 							<ObjectRef Name="play_sx_player_pain" ID="{C4E4C612-D934-451D-873B-D9B4AE45A646}" WorkUnitID="{6146481B-5849-48AD-9DBA-B2D263C55E44}"/>
 							<Position X="3" Y="1"/>

+ 0 - 0
credit.md → credits.md


+ 9 - 0
libs/gameaudio/wwise/multiplayersample_controls.xml

@@ -30,6 +30,15 @@
 		<ATLTrigger atl_name="Play_Sound_Gun_Firing" path="z_placeholders">
 			<WwiseEvent wwise_name="Play_Sound_Gun_Firing"/>
 		</ATLTrigger>
+		<ATLTrigger atl_name="rocket" path="Events/MUS">
+			<WwiseEvent wwise_name="rocket"/>
+		</ATLTrigger>
+		<ATLTrigger atl_name="future_gladiator" path="Events/MUS">
+			<WwiseEvent wwise_name="future_gladiator"/>
+		</ATLTrigger>
+		<ATLTrigger atl_name="beauty_flow" path="Events/MUS">
+			<WwiseEvent wwise_name="beauty_flow"/>
+		</ATLTrigger>
 		<ATLTrigger atl_name="set_state_game_none" path="Events/_Globals/States/Game">
 			<WwiseEvent wwise_name="set_state_game_none"/>
 		</ATLTrigger>