Merged dev
Signed-off-by: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com>
This commit is contained in:
@@ -35,7 +35,7 @@ namespace Multiplayer
|
||||
using EntityMigrationStartEvent = AZ::Event<ClientInputId>;
|
||||
using EntityMigrationEndEvent = AZ::Event<>;
|
||||
using EntityServerMigrationEvent = AZ::Event<const ConstNetworkEntityHandle&, HostId, AzNetworking::ConnectionId>;
|
||||
using EntityPreRenderEvent = AZ::Event<float, float>;
|
||||
using EntityPreRenderEvent = AZ::Event<float>;
|
||||
using EntityCorrectionEvent = AZ::Event<>;
|
||||
|
||||
//! @class NetBindComponent
|
||||
@@ -118,7 +118,7 @@ namespace Multiplayer
|
||||
void NotifyMigrationStart(ClientInputId migratedInputId);
|
||||
void NotifyMigrationEnd();
|
||||
void NotifyServerMigration(HostId hostId, AzNetworking::ConnectionId connectionId);
|
||||
void NotifyPreRender(float deltaTime, float blendFactor);
|
||||
void NotifyPreRender(float deltaTime);
|
||||
void NotifyCorrection();
|
||||
|
||||
void AddEntityStopEventHandler(EntityStopEvent::Handler& eventHandler);
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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 <Source/AutoGen/NetworkCharacterComponent.AutoComponent.h>
|
||||
#include <PhysX/CharacterGameplayBus.h>
|
||||
#include <Multiplayer/Components/NetBindComponent.h>
|
||||
|
||||
namespace Physics
|
||||
{
|
||||
class Character;
|
||||
}
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
//! NetworkCharacterComponent
|
||||
//! Provides multiplayer support for game-play player characters.
|
||||
class NetworkCharacterComponent
|
||||
: public NetworkCharacterComponentBase
|
||||
, private PhysX::CharacterGameplayRequestBus::Handler
|
||||
{
|
||||
friend class NetworkCharacterComponentController;
|
||||
|
||||
public:
|
||||
AZ_MULTIPLAYER_COMPONENT(Multiplayer::NetworkCharacterComponent, s_networkCharacterComponentConcreteUuid, Multiplayer::NetworkCharacterComponentBase)
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
NetworkCharacterComponent();
|
||||
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC_CE("NetworkRigidBodyService"));
|
||||
}
|
||||
|
||||
// AZ::Component
|
||||
void OnInit() override {}
|
||||
void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
|
||||
private:
|
||||
void OnTranslationChangedEvent(const AZ::Vector3& translation);
|
||||
void OnSyncRewind();
|
||||
|
||||
// CharacterGameplayRequestBus
|
||||
bool IsOnGround() const override;
|
||||
float GetGravityMultiplier() const override { return {}; }
|
||||
void SetGravityMultiplier([[maybe_unused]] float gravityMultiplier) override {}
|
||||
AZ::Vector3 GetFallingVelocity() const override { return {}; }
|
||||
void SetFallingVelocity([[maybe_unused]] const AZ::Vector3& fallingVelocity) override {}
|
||||
|
||||
Physics::Character* m_physicsCharacter = nullptr;
|
||||
Multiplayer::EntitySyncRewindEvent::Handler m_syncRewindHandler = Multiplayer::EntitySyncRewindEvent::Handler([this]() { OnSyncRewind(); });
|
||||
AZ::Event<AZ::Vector3>::Handler m_translationEventHandler;
|
||||
};
|
||||
|
||||
//! NetworkCharacterComponentController
|
||||
//! This is the network controller for NetworkCharacterComponent.
|
||||
//! Class provides the ability to move characters in physical space while keeping the network in-sync.
|
||||
class NetworkCharacterComponentController
|
||||
: public NetworkCharacterComponentControllerBase
|
||||
{
|
||||
public:
|
||||
NetworkCharacterComponentController(NetworkCharacterComponent& parent);
|
||||
|
||||
// NetworkCharacterComponentControllerBase
|
||||
void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
|
||||
//! TryMoveWithVelocity
|
||||
//! Will move this character entity kinematically through physical world while also ensuring the network stays in-sync.
|
||||
//! Velocity will be applied over delta-time to determine the movement amount.
|
||||
//! Returns this entity's world-space position after the move.
|
||||
AZ::Vector3 TryMoveWithVelocity(const AZ::Vector3& velocity, float deltaTime);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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 <Source/AutoGen/NetworkHitVolumesComponent.AutoComponent.h>
|
||||
#include <Multiplayer/Components/NetBindComponent.h>
|
||||
#include <Integration/ActorComponentBus.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
|
||||
namespace Physics
|
||||
{
|
||||
class CharacterRequests;
|
||||
class CharacterHitDetectionConfiguration;
|
||||
}
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
class NetworkHitVolumesComponent
|
||||
: public NetworkHitVolumesComponentBase
|
||||
, private EMotionFX::Integration::ActorComponentNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
struct AnimatedHitVolume final
|
||||
{
|
||||
AnimatedHitVolume
|
||||
(
|
||||
AzNetworking::ConnectionId connectionId,
|
||||
Physics::CharacterRequests* character,
|
||||
const char* hitVolumeName,
|
||||
const Physics::ColliderConfiguration* colliderConfig,
|
||||
const Physics::ShapeConfiguration* shapeConfig,
|
||||
const uint32_t jointIndex
|
||||
);
|
||||
|
||||
~AnimatedHitVolume() = default;
|
||||
|
||||
void UpdateTransform(const AZ::Transform& transform);
|
||||
void SyncToCurrentTransform();
|
||||
|
||||
Multiplayer::RewindableObject<AZ::Transform, Multiplayer::RewindHistorySize> m_transform;
|
||||
AZStd::shared_ptr<Physics::Shape> m_physicsShape;
|
||||
|
||||
// Cached so we don't have to do subsequent lookups by name
|
||||
const Physics::ColliderConfiguration* m_colliderConfig = nullptr;
|
||||
const Physics::ShapeConfiguration* m_shapeConfig = nullptr;
|
||||
AZ::Transform m_colliderOffSetTransform;
|
||||
const AZ::u32 m_jointIndex = 0;
|
||||
};
|
||||
|
||||
AZ_MULTIPLAYER_COMPONENT(Multiplayer::NetworkHitVolumesComponent, s_networkHitVolumesComponentConcreteUuid, Multiplayer::NetworkHitVolumesComponentBase);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
NetworkHitVolumesComponent();
|
||||
|
||||
void OnInit() override;
|
||||
void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
|
||||
private:
|
||||
void OnPreRender(float deltaTime);
|
||||
void OnTransformUpdate(const AZ::Transform& transform);
|
||||
void OnSyncRewind();
|
||||
|
||||
void CreateHitVolumes();
|
||||
void DestroyHitVolumes();
|
||||
|
||||
//! ActorComponentNotificationBus::Handler
|
||||
//! @{
|
||||
void OnActorInstanceCreated(EMotionFX::ActorInstance* actorInstance) override;
|
||||
void OnActorInstanceDestroyed(EMotionFX::ActorInstance* actorInstance) override;
|
||||
//! @}
|
||||
|
||||
Physics::CharacterRequests* m_physicsCharacter = nullptr;
|
||||
EMotionFX::Integration::ActorComponentRequests* m_actorComponent = nullptr;
|
||||
const Physics::CharacterColliderConfiguration* m_hitDetectionConfig = nullptr;
|
||||
|
||||
AZStd::vector<AnimatedHitVolume> m_animatedHitVolumes;
|
||||
|
||||
Multiplayer::EntitySyncRewindEvent::Handler m_syncRewindHandler;
|
||||
Multiplayer::EntityPreRenderEvent::Handler m_preRenderHandler;
|
||||
AZ::TransformChangedEvent::Handler m_transformChangedHandler;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 <Source/AutoGen/NetworkRigidBodyComponent.AutoComponent.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <Multiplayer/Components/NetBindComponent.h>
|
||||
|
||||
namespace Physics
|
||||
{
|
||||
class RigidBodyRequests;
|
||||
}
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
//! Bus for requests to the network rigid body component.
|
||||
class NetworkRigidBodyRequests : public AZ::ComponentBus
|
||||
{
|
||||
};
|
||||
using NetworkRigidBodyRequestBus = AZ::EBus<NetworkRigidBodyRequests>;
|
||||
|
||||
class NetworkRigidBodyComponent final
|
||||
: public NetworkRigidBodyComponentBase
|
||||
, private NetworkRigidBodyRequestBus::Handler
|
||||
{
|
||||
friend class NetworkRigidBodyComponentController;
|
||||
|
||||
public:
|
||||
AZ_MULTIPLAYER_COMPONENT(
|
||||
Multiplayer::NetworkRigidBodyComponent, s_networkRigidBodyComponentConcreteUuid, Multiplayer::NetworkRigidBodyComponentBase);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
|
||||
|
||||
NetworkRigidBodyComponent();
|
||||
|
||||
void OnInit() override;
|
||||
void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
|
||||
private:
|
||||
void OnTransformUpdate(const AZ::Transform& worldTm);
|
||||
void OnSyncRewind();
|
||||
|
||||
Multiplayer::EntitySyncRewindEvent::Handler m_syncRewindHandler;
|
||||
AZ::TransformChangedEvent::Handler m_transformChangedHandler;
|
||||
Physics::RigidBodyRequests* m_physicsRigidBodyComponent = nullptr;
|
||||
Multiplayer::RewindableObject<AZ::Transform, Multiplayer::RewindHistorySize> m_transform;
|
||||
};
|
||||
|
||||
class NetworkRigidBodyComponentController
|
||||
: public NetworkRigidBodyComponentControllerBase
|
||||
{
|
||||
public:
|
||||
NetworkRigidBodyComponentController(NetworkRigidBodyComponent& parent);
|
||||
|
||||
void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
|
||||
void HandleSendApplyImpulse(AzNetworking::IConnection* invokingConnection, const AZ::Vector3& impulse, const AZ::Vector3& worldPoint) override;
|
||||
};
|
||||
} // namespace Multiplayer
|
||||
@@ -29,26 +29,9 @@ namespace Multiplayer
|
||||
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
|
||||
private:
|
||||
void OnPreRender(float deltaTime, float blendFactor);
|
||||
void OnPreRender(float deltaTime);
|
||||
void OnCorrection();
|
||||
|
||||
void OnRotationChangedEvent(const AZ::Quaternion& rotation);
|
||||
void OnTranslationChangedEvent(const AZ::Vector3& translation);
|
||||
void OnScaleChangedEvent(float scale);
|
||||
void OnResetCountChangedEvent();
|
||||
void OnParentIdChangedEvent(NetEntityId newParent);
|
||||
|
||||
void UpdateTargetHostFrameId();
|
||||
|
||||
AZ::Transform m_previousTransform = AZ::Transform::CreateIdentity();
|
||||
AZ::Transform m_targetTransform = AZ::Transform::CreateIdentity();
|
||||
|
||||
AZ::Event<AZ::Quaternion>::Handler m_rotationEventHandler;
|
||||
AZ::Event<AZ::Vector3>::Handler m_translationEventHandler;
|
||||
AZ::Event<float>::Handler m_scaleEventHandler;
|
||||
AZ::Event<uint8_t>::Handler m_resetCountEventHandler;
|
||||
AZ::Event<NetEntityId>::Handler m_parentIdChangedEventHandler;
|
||||
|
||||
EntityPreRenderEvent::Handler m_entityPreRenderEventHandler;
|
||||
EntityCorrectionEvent::Handler m_entityCorrectionEventHandler;
|
||||
|
||||
|
||||
@@ -193,15 +193,13 @@ namespace Multiplayer
|
||||
m_previousHostFrameId = time->GetHostFrameId();
|
||||
m_previousHostTimeMs = time->GetHostTimeMs();
|
||||
m_previousRewindConnectionId = time->GetRewindingConnectionId();
|
||||
time->AlterTime(frameId, timeMs, connectionId);
|
||||
m_previousBlendFactor = time->GetHostBlendFactor();
|
||||
time->AlterBlendFactor(blendFactor);
|
||||
time->AlterTime(frameId, timeMs, blendFactor, connectionId);
|
||||
}
|
||||
inline ~ScopedAlterTime()
|
||||
{
|
||||
INetworkTime* time = GetNetworkTime();
|
||||
time->AlterTime(m_previousHostFrameId, m_previousHostTimeMs, m_previousRewindConnectionId);
|
||||
time->AlterBlendFactor(m_previousBlendFactor);
|
||||
time->AlterTime(m_previousHostFrameId, m_previousHostTimeMs, m_previousBlendFactor, m_previousRewindConnectionId);
|
||||
}
|
||||
private:
|
||||
HostFrameId m_previousHostFrameId = InvalidHostFrameId;
|
||||
|
||||
@@ -52,12 +52,6 @@ namespace Multiplayer
|
||||
//! @return the ConnectionId of the connection requesting the rewind operation
|
||||
virtual AzNetworking::ConnectionId GetRewindingConnectionId() const = 0;
|
||||
|
||||
//! Get the controlling connection that may be currently altering global game time.
|
||||
//! Note this abstraction is required at a relatively high level to allow for 'don't rewind the shooter' semantics
|
||||
//! @param rewindConnectionId if this parameter matches the current rewindConnectionId, it will return the unaltered hostFrameId
|
||||
//! @return the HostFrameId taking into account the provided rewinding connectionId
|
||||
virtual HostFrameId GetHostFrameIdForRewindingConnection(AzNetworking::ConnectionId rewindConnectionId) const = 0;
|
||||
|
||||
//! Forcibly sets the current network time to the provided frameId and game time in milliseconds.
|
||||
//! @param frameId the new HostFrameId to use
|
||||
//! @param timeMs the new HostTimeMs to use
|
||||
@@ -66,12 +60,9 @@ namespace Multiplayer
|
||||
//! Alters the current HostFrameId and binds that alteration to the provided ConnectionId.
|
||||
//! @param frameId the new HostFrameId to use
|
||||
//! @param timeMs the new HostTimeMs to use
|
||||
//! @param blendFactor the factor used to blend between values at the current and previous HostFrameId
|
||||
//! @param rewindConnectionId the rewinding ConnectionId
|
||||
virtual void AlterTime(HostFrameId frameId, AZ::TimeMs timeMs, AzNetworking::ConnectionId rewindConnectionId) = 0;
|
||||
|
||||
//! Alters the current Host blend factor. Used to drive interpolation in rewound states.
|
||||
//! @param blendFactor the blend factor to use
|
||||
virtual void AlterBlendFactor(float blendFactor) = 0;
|
||||
virtual void AlterTime(HostFrameId frameId, AZ::TimeMs timeMs, float blendFactor, AzNetworking::ConnectionId rewindConnectionId) = 0;
|
||||
|
||||
//! Syncs all entities contained within a volume to the current rewind state.
|
||||
//! @param rewindVolume the volume to rewind entities within (needed for physics entities)
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Multiplayer
|
||||
//! @return value in const base type form
|
||||
const BASE_TYPE& Get() const;
|
||||
|
||||
//! Const base type retriever for one host frame behind Get(). Only intended for use in SyncRewind contexts.
|
||||
//! Const base type retriever for one host frame behind Get() when contextually appropriate, otherwise identical to Get().
|
||||
//! @return value in const base type form
|
||||
const BASE_TYPE& GetPrevious() const;
|
||||
|
||||
@@ -86,9 +86,13 @@ namespace Multiplayer
|
||||
private:
|
||||
|
||||
//! Returns what the appropriate current time is for this rewindable property.
|
||||
//! @return the appropriate current time is for this rewindable property
|
||||
//! @return the appropriate current time for this rewindable property
|
||||
HostFrameId GetCurrentTimeForProperty() const;
|
||||
|
||||
//! Returns what the appropriate previous time is for this rewindable property.
|
||||
//! @return the appropriate previous time for this rewindable property
|
||||
HostFrameId GetPreviousTimeForProperty() const;
|
||||
|
||||
//! Updates the latest value for this object instance, if frameTime represents a current or future time.
|
||||
//! Any attempts to set old values on the object will fail
|
||||
//! @param value the new value to set in the object history
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Multiplayer
|
||||
template <typename BASE_TYPE, AZStd::size_t REWIND_SIZE>
|
||||
inline const BASE_TYPE& RewindableObject<BASE_TYPE, REWIND_SIZE>::GetPrevious() const
|
||||
{
|
||||
return GetValueForTime(GetCurrentTimeForProperty() - HostFrameId(1));
|
||||
return GetValueForTime(GetPreviousTimeForProperty());
|
||||
}
|
||||
|
||||
template <typename BASE_TYPE, AZStd::size_t REWIND_SIZE>
|
||||
@@ -118,7 +118,22 @@ namespace Multiplayer
|
||||
inline HostFrameId RewindableObject<BASE_TYPE, REWIND_SIZE>::GetCurrentTimeForProperty() const
|
||||
{
|
||||
INetworkTime* networkTime = Multiplayer::GetNetworkTime();
|
||||
return networkTime->GetHostFrameIdForRewindingConnection(m_owningConnectionId);
|
||||
if (networkTime->IsTimeRewound() && (m_owningConnectionId == networkTime->GetRewindingConnectionId()))
|
||||
{
|
||||
return networkTime->GetUnalteredHostFrameId();
|
||||
}
|
||||
return networkTime->GetHostFrameId();
|
||||
}
|
||||
|
||||
template <typename BASE_TYPE, AZStd::size_t REWIND_SIZE>
|
||||
inline HostFrameId RewindableObject<BASE_TYPE, REWIND_SIZE>::GetPreviousTimeForProperty() const
|
||||
{
|
||||
INetworkTime* networkTime = Multiplayer::GetNetworkTime();
|
||||
if (networkTime->IsTimeRewound() && (m_owningConnectionId == networkTime->GetRewindingConnectionId()))
|
||||
{
|
||||
return networkTime->GetUnalteredHostFrameId();
|
||||
}
|
||||
return networkTime->GetHostFrameId() - HostFrameId(1);
|
||||
}
|
||||
|
||||
template <typename BASE_TYPE, AZStd::size_t REWIND_SIZE>
|
||||
|
||||
Reference in New Issue
Block a user