Selaa lähdekoodia

Changes to make energy balls explode on first impact, and also provide a lifetime parameter to control how long energy balls live for. Changes to allow weapon impacts to be handled from script for additional weapon effects hookup

Signed-off-by: kberg-amzn <[email protected]>
kberg-amzn 2 vuotta sitten
vanhempi
commit
40dbea5035

+ 11 - 1
Gem/Code/Include/WeaponNotificationBus.h

@@ -12,11 +12,21 @@
 
 namespace MultiplayerSample
 {
-    class WeaponNotifications : public AZ::EBusTraits
+    class WeaponNotifications
+        : public AZ::EBusTraits
     {
     public:
         virtual ~WeaponNotifications() = default;
 
+        //! Called on a local player that has activated a weapon.
+        virtual void OnWeaponActivate([[maybe_unused]] const AZ::Transform& transform) {}
+
+        //! Called on a local player that has predictively impacted something with a weapon.
+        virtual void OnWeaponImpact([[maybe_unused]] const AZ::Transform& transform) {}
+
+        //! Called on a local player that has confirmed damaged something with a weapon.
+        virtual void OnWeaponDamage([[maybe_unused]] const AZ::Transform& transform) {}
+
         //! Called on a local player that has been confirmed to hit a player with a weapon.
         virtual void OnConfirmedHitPlayer([[maybe_unused]] AZ::EntityId byPlayerEntity, [[maybe_unused]] AZ::EntityId otherPlayerEntity) {}
     };

+ 7 - 2
Gem/Code/Source/AutoGen/EnergyBallComponent.AutoComponent.xml

@@ -17,13 +17,18 @@
     <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.">
+    <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.">
         <Param Type="AZ::Vector3" Name="StartingPosition"/>
         <Param Type="AZ::Vector3" Name="Direction"/>
         <Param Type="Multiplayer::NetEntityId" Name="OwningNetEntityId" />
     </RemoteProcedure>
 
+    <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="AZ::Vector3" Name="Location"/>
     </RemoteProcedure>

+ 3 - 1
Gem/Code/Source/AutoGen/EnergyCannonComponent.AutoComponent.xml

@@ -13,7 +13,9 @@
     <ComponentRelation Constraint="Required" HasController="true" Name="NetworkTransformComponent" Namespace="Multiplayer" Include="Multiplayer/Components/NetworkTransformComponent.h" />
 
     <ArchetypeProperty Type="AZ::TimeMs" Name="RateOfFireMs" Init="" Container="Object" ExposeToEditor="true" 
-                       Description="Specifies the rate in milliseconds at which to fire projectiles, each cannon can only fire a single projectile at once so this also controls the projectile lifetime" />
+                       Description="Specifies the rate in milliseconds at which to fire projectiles, each cannon can only fire a single projectile at once so this also controls the projectile lifetime." />
+    <ArchetypeProperty Type="AZ::TimeMs" Name="BallLifetimeMs" Init="" Container="Object" ExposeToEditor="true"
+                       Description="Specifies the duration in milliseconds that the energy ball should live for. Must be less than the RateOfFireMs setting." />
     <ArchetypeProperty Type="GameEffect" Name="FiringEffect" Init="" Container="Object" ExposeToEditor="true" Description="Specifies the effect to play upon firing" />
     <ArchetypeProperty Type="AZ::EntityId" Name="EnergyBallEntity" ExposeToEditor="true" Description="The entity representing an energy ball." />
 

+ 1 - 1
Gem/Code/Source/AutoGen/NetworkWeaponsComponent.AutoComponent.xml

@@ -25,7 +25,7 @@
     <ArchetypeProperty Type="WeaponParams"  Name="WeaponParams"  Init="" Container="Array" Count="MaxWeaponsPerComponent" ExposeToEditor="true" Description="Parameters for the weapons attached to this NetworkWeaponsComponent" />
     <ArchetypeProperty Type="AZStd::string" Name="FireBoneNames" Init="" Container="Array" Count="MaxWeaponsPerComponent" ExposeToEditor="true" Description="Name of the bone to attach to for fire events" />
 
-    <RemoteProcedure Name="SendConfirmHit" InvokeFrom="Authority" HandleOn="Client" IsPublic="false" IsReliable="false" GenerateEventBindings="false" Description="Single hit event confirmed by the server" >
+    <RemoteProcedure Name="SendConfirmHit" InvokeFrom="Authority" HandleOn="Client" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="Single hit event confirmed by the server" >
         <Param Type="WeaponIndex" Name="WeaponIndex" />
         <Param Type="HitEvent"    Name="HitEvent" />
     </RemoteProcedure>

+ 30 - 4
Gem/Code/Source/Components/Multiplayer/EnergyBallComponent.cpp

@@ -13,6 +13,10 @@
 #include <AzCore/Component/TransformBus.h>
 #include <AzFramework/Physics/RigidBodyBus.h>
 
+#if AZ_TRAIT_CLIENT
+#   include <PopcornFX/PopcornFXBus.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");
@@ -39,10 +43,25 @@ namespace MultiplayerSample
     }
 
 #if AZ_TRAIT_CLIENT
+    void EnergyBallComponent::HandleRPC_BallLaunched([[maybe_unused]] AzNetworking::IConnection* invokingConnection, [[maybe_unused]] const AZ::Vector3& location)
+    {
+        PopcornFX::PopcornFXEmitterComponentRequests* emitterRequests = PopcornFX::PopcornFXEmitterComponentRequestBus::FindFirstHandler(GetEntity()->GetId());
+        if (emitterRequests != nullptr)
+        {
+            emitterRequests->Start();
+        }
+    }
+
     void EnergyBallComponent::HandleRPC_BallExplosion([[maybe_unused]] AzNetworking::IConnection* invokingConnection, const AZ::Vector3& location)
     {
         AZ::Transform transform = AZ::Transform::CreateFromQuaternionAndTranslation(AZ::Quaternion::CreateIdentity(), location);
         m_effect.TriggerEffect(transform);
+
+        PopcornFX::PopcornFXEmitterComponentRequests* emitterRequests = PopcornFX::PopcornFXEmitterComponentRequestBus::FindFirstHandler(GetEntity()->GetId());
+        if (emitterRequests != nullptr)
+        {
+            emitterRequests->Kill();
+        }
     }
 #endif
 
@@ -69,7 +88,7 @@ namespace MultiplayerSample
 #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)
     {
-        HideEnergyBall();
+        m_shooterNetEntityId = owningNetEntityId;
 
         m_filteredNetEntityIds.clear();
         m_filteredNetEntityIds.insert(owningNetEntityId);
@@ -82,6 +101,13 @@ namespace MultiplayerSample
 
         Physics::RigidBodyRequestBus::Event(GetEntityId(), &Physics::RigidBodyRequestBus::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)
+    {
+        HideEnergyBall();
     }
 
     void EnergyBallComponentController::CheckForCollisions()
@@ -90,18 +116,18 @@ namespace MultiplayerSample
         const HitEffect& effect = GetHitEffect();
 
         IntersectResults results;
-        const ActivateEvent activateEvent{ GetEntity()->GetTransform()->GetWorldTM(), position, Multiplayer::InvalidNetEntityId, Multiplayer::InvalidNetEntityId };
+        const ActivateEvent activateEvent{ GetEntity()->GetTransform()->GetWorldTM(), position, m_shooterNetEntityId, GetNetEntityId() };
         GatherEntities(GetGatherParams(), activateEvent, m_filteredNetEntityIds, results);
         if (!results.empty())
         {
             bool shouldTerminate = false;
             for (const IntersectResult& result : results)
             {
+                shouldTerminate = true;
+
                 Multiplayer::ConstNetworkEntityHandle handle = Multiplayer::GetMultiplayer()->GetNetworkEntityManager()->GetEntity(result.m_netEntityId);
                 if (handle.Exists())
                 {
-                    shouldTerminate = true;
-
                     // Presently set to 1 until we capture falloff range
                     float hitDistance = 1.f;
                     float maxDistance = 1.f;

+ 3 - 0
Gem/Code/Source/Components/Multiplayer/EnergyBallComponent.h

@@ -24,6 +24,7 @@ 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 AZ::Vector3& location) override;
 #endif
 
@@ -42,6 +43,7 @@ namespace MultiplayerSample
 
 #if AZ_TRAIT_SERVER
         void HandleRPC_LaunchBall(AzNetworking::IConnection* invokingConnection, const AZ::Vector3& startingPosition, const AZ::Vector3& direction, const Multiplayer::NetEntityId& owningNetEntityId) override;
+        void HandleRPC_KillBall(AzNetworking::IConnection* invokingConnection) override;
         void CheckForCollisions();
         void HideEnergyBall();
 
@@ -52,6 +54,7 @@ namespace MultiplayerSample
         }, AZ::Name("EnergyBallCheckForCollisions") };
 
         AZ::Vector3 m_direction = AZ::Vector3::CreateZero();
+        Multiplayer::NetEntityId m_shooterNetEntityId = Multiplayer::InvalidNetEntityId;
         NetEntityIdSet m_filteredNetEntityIds;
 #endif
     };

+ 17 - 0
Gem/Code/Source/Components/Multiplayer/EnergyCannonComponent.cpp

@@ -81,6 +81,23 @@ namespace MultiplayerSample
                 const AZ::Vector3 effectOffset = GetFiringEffect().GetEffectOffset();
                 ballComponent->RPC_LaunchBall(cannonTm.GetTranslation() + effectOffset, forward, GetNetEntityId());
                 RPC_BallLaunched();
+
+                // Enqueue our ball kill event
+                m_killEvent.Enqueue(GetBallLifetimeMs(), false);
+            }
+        }
+    }
+
+    void EnergyCannonComponentController::OnKillEnergyBall()
+    {
+        // Re-using the same ball entity.
+        AZ::Entity* ball = nullptr;
+        AZ::ComponentApplicationBus::BroadcastResult(ball, &AZ::ComponentApplicationBus::Events::FindEntity, GetEnergyBallEntity());
+        if (ball)
+        {
+            if (EnergyBallComponent* ballComponent = ball->FindComponent<EnergyBallComponent>())
+            {
+                ballComponent->RPC_KillBall();
             }
         }
     }

+ 7 - 1
Gem/Code/Source/Components/Multiplayer/EnergyCannonComponent.h

@@ -45,7 +45,13 @@ namespace MultiplayerSample
         AZ::ScheduledEvent m_firingEvent{[this]()
         {
             OnFireEnergyBall();
-        }, AZ::Name("EnergyCannonComponentController")};
+        }, AZ::Name("FireEnergyCannon")};
+
+        void OnKillEnergyBall();
+        AZ::ScheduledEvent m_killEvent{ [this]()
+        {
+            OnKillEnergyBall();
+        }, AZ::Name("KillEnergyBall") };
 #endif
     };
 }

+ 21 - 0
Gem/Code/Source/Components/NetworkWeaponsComponent.cpp

@@ -40,8 +40,26 @@ namespace MultiplayerSample
     {
     public:
         AZ_EBUS_BEHAVIOR_BINDER(BehaviorWeaponNotificationBusHandler, "{8F083B95-4519-4A24-8824-ED5ADA8FC52E}", AZ::SystemAllocator,
+            OnWeaponActivate,
+            OnWeaponImpact,
+            OnWeaponDamage,
             OnConfirmedHitPlayer);
 
+        void OnWeaponActivate(const AZ::Transform& transform) override
+        {
+            Call(FN_OnWeaponActivate, transform);
+        }
+
+        void OnWeaponImpact(const AZ::Transform& transform) override
+        {
+            Call(FN_OnWeaponImpact, transform);
+        }
+
+        void OnWeaponDamage(const AZ::Transform& transform) override
+        {
+            Call(FN_OnWeaponDamage, transform);
+        }
+
         void OnConfirmedHitPlayer(AZ::EntityId byPlayerEntity, AZ::EntityId otherPlayerEntity) override
         {
             Call(FN_OnConfirmedHitPlayer, byPlayerEntity, otherPlayerEntity);
@@ -165,6 +183,7 @@ namespace MultiplayerSample
         }
 
         m_onWeaponActivateEvent.Signal(activationInfo);
+        WeaponNotificationBus::Broadcast(&WeaponNotificationBus::Events::OnWeaponActivate, activationInfo.m_activateEvent.m_initialTransform);
 
 #if AZ_TRAIT_CLIENT
         if (cl_WeaponsDrawDebug && m_debugDraw)
@@ -214,6 +233,7 @@ namespace MultiplayerSample
         }
 
         m_onWeaponPredictHitEvent.Signal(hitInfo);
+        WeaponNotificationBus::Broadcast(&WeaponNotificationBus::Events::OnWeaponImpact, hitInfo.m_hitEvent.m_hitTransform);
 
         for (const auto& hitEntity : hitInfo.m_hitEvent.m_hitEntities)
         {
@@ -286,6 +306,7 @@ namespace MultiplayerSample
 #endif
 
         m_onWeaponConfirmHitEvent.Signal(hitInfo);
+        WeaponNotificationBus::Broadcast(&WeaponNotificationBus::Events::OnWeaponDamage, hitInfo.m_hitEvent.m_hitTransform);
 
         // 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
         // Note that materialfx are not hooked up currently as the engine currently doesn't support them

+ 3 - 2
Gem/Code/Source/MultiplayerSampleSystemComponent.cpp

@@ -28,6 +28,8 @@ namespace MultiplayerSample
         ReflectWeaponEnums(context);
         GatherParams::Reflect(context);
         HitEffect::Reflect(context);
+        HitEntity::Reflect(context);
+        HitEvent::Reflect(context);
         WeaponParams::Reflect(context);
         GameEffect::Reflect(context);
 
@@ -38,8 +40,7 @@ namespace MultiplayerSample
         if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
         {
             serialize->Class<MultiplayerSampleSystemComponent, AZ::Component>()
-                ->Version(0)
-                ;
+                ->Version(0);
 
             if (AZ::EditContext* ec = serialize->GetEditContext())
             {

+ 52 - 0
Gem/Code/Source/Weapons/WeaponTypes.cpp

@@ -351,6 +351,31 @@ namespace MultiplayerSample
             && serializer.Serialize(m_hitNetEntityId, "HitNetEntityId");
     }
 
+    void HitEntity::Reflect(AZ::ReflectContext* context)
+    {
+        AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
+        if (serializeContext)
+        {
+            serializeContext->Class<HitEntity>()
+                ->Version(0)
+                ->Field("HitPosition", &HitEntity::m_hitPosition)
+                ->Field("HitNetEntityId", &HitEntity::m_hitNetEntityId);
+        }
+
+        AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
+        if (behaviorContext)
+        {
+            behaviorContext->Class<HitEntity>("HitEntity")
+                ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
+                ->Attribute(AZ::Script::Attributes::Module, "multiplayersample")
+                ->Attribute(AZ::Script::Attributes::Category, "MultiplayerSample")
+                ->Constructor<>()
+                ->Property("HitPosition", BehaviorValueProperty(&HitEntity::m_hitPosition))
+                ->Property("HitNetEntityId", BehaviorValueProperty(&HitEntity::m_hitNetEntityId))
+                ;
+        }
+    }
+
     bool HitEvent::Serialize(AzNetworking::ISerializer& serializer)
     {
         return serializer.Serialize(m_hitTransform, "HitTransform")
@@ -358,6 +383,33 @@ namespace MultiplayerSample
             && serializer.Serialize(m_hitEntities, "HitEntities");
     }
 
+    void HitEvent::Reflect(AZ::ReflectContext* context)
+    {
+        AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
+        if (serializeContext)
+        {
+            serializeContext->Class<HitEvent>()
+                ->Version(0)
+                ->Field("HitTransform", &HitEvent::m_hitTransform)
+                ->Field("ShooterNetEntityId", &HitEvent::m_shooterNetEntityId)
+                ->Field("HitEntities", &HitEvent::m_hitEntities);
+        }
+
+        AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
+        if (behaviorContext)
+        {
+            behaviorContext->Class<HitEvent>("HitEvent")
+                ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
+                ->Attribute(AZ::Script::Attributes::Module, "multiplayersample")
+                ->Attribute(AZ::Script::Attributes::Category, "MultiplayerSample")
+                ->Constructor<>()
+                ->Property("HitTransform", BehaviorValueProperty(&HitEvent::m_hitTransform))
+                ->Property("ShooterNetEntityId", BehaviorValueProperty(&HitEvent::m_shooterNetEntityId))
+                ->Property("HitEntities", BehaviorValueProperty(&HitEvent::m_hitEntities))
+                ;
+        }
+    }
+
     bool FireParams::operator!=(const FireParams& rhs) const
     {
         return !m_targetPosition.IsClose(rhs.m_targetPosition)

+ 7 - 1
Gem/Code/Source/Weapons/WeaponTypes.h

@@ -170,22 +170,28 @@ namespace MultiplayerSample
     //! Single hit entity in a weapon hit event.
     struct HitEntity
     {
+        AZ_TYPE_INFO(HitEntity, "{A7A0A64A-816C-4675-9A02-652A72CD2255}");
+
         AZ::Vector3 m_hitPosition = AZ::Vector3::CreateZero(); // Location where the entity was hit, NOT the location of the projectile or weapon in the case of area damage
         Multiplayer::NetEntityId m_hitNetEntityId = Multiplayer::InvalidNetEntityId; // Entity Id of the entity which was hit
 
         bool Serialize(AzNetworking::ISerializer& serializer);
+        static void Reflect(AZ::ReflectContext* context);
     };
-    using HitEntities = AZStd::fixed_vector<HitEntity, MaxHitEntities>;
+    using HitEntities = AZStd::vector<HitEntity>;
 
     //! Structure containing details for a single weapon hit event.
     struct HitEvent
     {
+        AZ_TYPE_INFO(HitEvent, "{573515BB-E806-42C1-9F2C-2AA1B8E2EEF0}");
+
         AZ::Transform m_hitTransform = AZ::Transform::CreateIdentity(); // Transform of the hit event, NOT the location of the entity that was hit in the case of area damage
         Multiplayer::NetEntityId m_shooterNetEntityId    = Multiplayer::InvalidNetEntityId; // Entity Id of the shooter
         Multiplayer::NetEntityId m_projectileNetEntityId = Multiplayer::InvalidNetEntityId; // Entity Id of the projectile, InvalidNetEntityId if this was a trace weapon hit
         HitEntities m_hitEntities; // Information about the entities that were hit
 
         bool Serialize(AzNetworking::ISerializer& serializer);
+        static void Reflect(AZ::ReflectContext* context);
     };
 
     //! Structure containing details for a single fire event.

+ 84 - 7
Levels/GameplayTest/GameplayTest.prefab

@@ -101,6 +101,8 @@
                     "Entity_[19602192101539]",
                     "Entity_[1800029023887]",
                     "Entity_[1808618958479]",
+                    "Instance_[9370273991746]/ContainerEntity",
+                    "Instance_[9344504187970]/ContainerEntity",
                     "Instance_[1787144121999]/ContainerEntity",
                     "Entity_[15271318338734]",
                     "Entity_[15438822063278]",
@@ -4995,9 +4997,9 @@
                     "Parent Entity": "Entity_[356758116574]",
                     "Transform Data": {
                         "Translate": [
-                            -3.749812126159668,
+                            -3.7022008895874023,
                             11.176107406616211,
-                            1.4368513822555542
+                            1.4251127243041992
                         ]
                     }
                 },
@@ -5551,9 +5553,9 @@
                     "Parent Entity": "Entity_[356758116574]",
                     "Transform Data": {
                         "Translate": [
-                            -7.148715496063232,
+                            -7.079329490661621,
                             11.176107406616211,
-                            2.8671789169311523
+                            2.849938154220581
                         ]
                     }
                 },
@@ -10425,6 +10427,21 @@
                     "op": "replace",
                     "path": "/ContainerEntity/Components/Component_[10406703446304744333]/Transform Data/Translate/2",
                     "value": -0.01335453987121582
+                },
+                {
+                    "op": "replace",
+                    "path": "/Entities/Entity_[1104171344821059]/Components/Component_[39629120857318069]/configuration/propertyOverrides/overrides/0/Datum/value/0",
+                    "value": -15.0
+                },
+                {
+                    "op": "replace",
+                    "path": "/Entities/Entity_[1104171344821059]/Components/Component_[39629120857318069]/configuration/propertyOverrides/overrides/0/Datum/value/1",
+                    "value": 3.0
+                },
+                {
+                    "op": "replace",
+                    "path": "/Entities/Entity_[1104171344821059]/Components/Component_[39629120857318069]/configuration/propertyOverrides/overrides/0/Datum/value/2",
+                    "value": 30.0
                 }
             ]
         },
@@ -11000,17 +11017,17 @@
                 {
                     "op": "replace",
                     "path": "/ContainerEntity/Components/Component_[16896350622714100755]/Transform Data/Translate/0",
-                    "value": 13.624070167541504
+                    "value": 13.378348350524902
                 },
                 {
                     "op": "replace",
                     "path": "/ContainerEntity/Components/Component_[16896350622714100755]/Transform Data/Translate/1",
-                    "value": -4.622063159942627
+                    "value": -8.48344612121582
                 },
                 {
                     "op": "replace",
                     "path": "/ContainerEntity/Components/Component_[16896350622714100755]/Transform Data/Translate/2",
-                    "value": -0.02269315905869007
+                    "value": -0.02269316278398037
                 },
                 {
                     "op": "replace",
@@ -12409,6 +12426,66 @@
                 }
             ]
         },
+        "Instance_[9344504187970]": {
+            "Source": "EBarricade/EBarricade.prefab",
+            "Patches": [
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/Component_[8879157216575694980]/Parent Entity",
+                    "value": "../Entity_[356758116574]"
+                },
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/Component_[8879157216575694980]/Transform Data/Translate/0",
+                    "value": -9.279814720153809
+                },
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/Component_[8879157216575694980]/Transform Data/Translate/1",
+                    "value": -12.245059967041016
+                },
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/Component_[8879157216575694980]/Transform Data/Translate/2",
+                    "value": -0.08922576904296875
+                },
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/Component_[8879157216575694980]/Transform Data/Rotate/2",
+                    "value": -143.00021362304688
+                }
+            ]
+        },
+        "Instance_[9370273991746]": {
+            "Source": "EBarricade/EBarricade.prefab",
+            "Patches": [
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/Component_[8879157216575694980]/Parent Entity",
+                    "value": "../Entity_[356758116574]"
+                },
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/Component_[8879157216575694980]/Transform Data/Translate/0",
+                    "value": -4.886531829833984
+                },
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/Component_[8879157216575694980]/Transform Data/Translate/1",
+                    "value": -12.245059967041016
+                },
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/Component_[8879157216575694980]/Transform Data/Translate/2",
+                    "value": -0.08922576904296875
+                },
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/Component_[8879157216575694980]/Transform Data/Rotate/2",
+                    "value": -143.00021362304688
+                }
+            ]
+        },
         "Instance_[990233405078]": {
             "Source": "MalfunctioningShieldGenerator/mshieldgen.prefab",
             "Patches": [

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 421 - 180
Prefabs/4x4x4BoxGrid.prefab


+ 5 - 1
Registry/physxdebugconfiguration.setreg

@@ -3,7 +3,11 @@
         "Gems": {
             "PhysX": {
                 "Debug": {
-                    "PhysXDebugConfiguration": {}
+                    "PhysXDebugConfiguration": {
+                        "PvdConfigurationData": {
+                            "AutoConnectMode": 2
+                        }
+                    }
                 }
             }
         }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 106 - 155
scriptcanvas/PredictiveJumpPad.scriptcanvas


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 324 - 160
scriptcanvas/ReticleEffects.scriptcanvas


Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä