Merging latest development

Signed-off-by: kberg-amzn <karlberg@amazon.com>
This commit is contained in:
kberg-amzn
2021-09-27 15:50:22 -07:00
482 changed files with 10637 additions and 2735 deletions
@@ -191,6 +191,8 @@ namespace Multiplayer
friend class NetworkEntityManager;
friend class EntityReplicationManager;
friend class HierarchyTests;
};
bool NetworkRoleHasController(NetEntityRole networkRole);
@@ -19,6 +19,21 @@ namespace Physics
namespace Multiplayer
{
//! NetworkCharacterRequests
//! ComponentBus handled by NetworkCharacterComponentController.
//! Bus was created for exposing controller methods to script; C++ users should access the controller directly.
class NetworkCharacterRequests : public AZ::ComponentBus
{
public:
//! 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.
virtual AZ::Vector3 TryMoveWithVelocity(const AZ::Vector3& velocity, float deltaTime) = 0;
};
typedef AZ::EBus<NetworkCharacterRequests> NetworkCharacterRequestBus;
//! NetworkCharacterComponent
//! Provides multiplayer support for game-play player characters.
class NetworkCharacterComponent
@@ -31,6 +46,7 @@ namespace Multiplayer
AZ_MULTIPLAYER_COMPONENT(Multiplayer::NetworkCharacterComponent, s_networkCharacterComponentConcreteUuid, Multiplayer::NetworkCharacterComponentBase)
static void Reflect(AZ::ReflectContext* context);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
NetworkCharacterComponent();
@@ -61,18 +77,22 @@ namespace Multiplayer
//! Class provides the ability to move characters in physical space while keeping the network in-sync.
class NetworkCharacterComponentController
: public NetworkCharacterComponentControllerBase
, private NetworkCharacterRequestBus::Handler
{
public:
AZ_RTTI(NetworkCharacterComponentController, "{C91851A2-8B95-4484-9F97-BFF9D1F528A0}")
static void Reflect(AZ::ReflectContext* context);
NetworkCharacterComponentController(NetworkCharacterComponent& parent);
// NetworkCharacterComponentControllerBase
void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
// NetworkCharacterRequestBus::Handler
//! 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);
AZ::Vector3 TryMoveWithVelocity(const AZ::Vector3& velocity, float deltaTime) override;
};
}
@@ -0,0 +1,48 @@
/*
* 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/ComponentBus.h>
namespace Multiplayer
{
using NetworkHierarchyChangedEvent = AZ::Event<const AZ::EntityId&>;
using NetworkHierarchyLeaveEvent = AZ::Event<>;
class NetworkHierarchyRequests
: public AZ::ComponentBus
{
public:
//! @returns true if the entity a hierarchical component attached should be considered for inclusion in a hierarchy
//! this should return false when an entity is deactivating
virtual bool IsHierarchyEnabled() const = 0;
//! @returns hierarchical entities, the first element is the top level root
virtual AZStd::vector<AZ::Entity*> GetHierarchicalEntities() const = 0;
//! @returns the top level root of a hierarchy, or nullptr if this entity is not in a hierarchy
virtual AZ::Entity* GetHierarchicalRoot() const = 0;
//! @return true if this entity is a child entity within a hierarchy
virtual bool IsHierarchicalChild() const = 0;
//! @return true if this entity is the top level root of a hierarchy
virtual bool IsHierarchicalRoot() const = 0;
//! Binds the provided NetworkHierarchyChangedEvent handler to a Network Hierarchy component.
//! @param handler the handler to invoke when the entity's network hierarchy has been modified.
virtual void BindNetworkHierarchyChangedEventHandler(NetworkHierarchyChangedEvent::Handler& handler) = 0;
//! Binds the provided NetworkHierarchyLeaveEvent handler to a Network Hierarchy component.
//! @param handler the handler to invoke when the entity left its network hierarchy.
virtual void BindNetworkHierarchyLeaveEventHandler(NetworkHierarchyLeaveEvent::Handler& handler) = 0;
};
typedef AZ::EBus<NetworkHierarchyRequests> NetworkHierarchyRequestBus;
}
@@ -0,0 +1,86 @@
/*
* 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 <AzCore/Component/TransformBus.h>
#include <Multiplayer/Components/NetworkHierarchyBus.h>
#include <Source/AutoGen/NetworkHierarchyChildComponent.AutoComponent.h>
namespace Multiplayer
{
class NetworkHierarchyRootComponent;
//! @class NetworkHierarchyChildComponent
//! @brief Component that declares network dependency on the parent of this entity
/*
* The parent of this entity should have @NetworkHierarchyChildComponent (or @NetworkHierarchyRootComponent).
* A network hierarchy is a collection of entities with one @NetworkHierarchyRootComponent at the top parent
* and one or more @NetworkHierarchyChildComponent on its child entities.
*/
class NetworkHierarchyChildComponent final
: public NetworkHierarchyChildComponentBase
, public NetworkHierarchyRequestBus::Handler
{
friend class NetworkHierarchyRootComponent;
public:
AZ_MULTIPLAYER_COMPONENT(Multiplayer::NetworkHierarchyChildComponent, s_networkHierarchyChildComponentConcreteUuid, Multiplayer::NetworkHierarchyChildComponentBase);
static void Reflect(AZ::ReflectContext* context);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
NetworkHierarchyChildComponent();
//! NetworkHierarchyChildComponentBase overrides.
//! @{
void OnInit() override;
void OnActivate(EntityIsMigrating entityIsMigrating) override;
void OnDeactivate(EntityIsMigrating entityIsMigrating) override;
//! @}
//! NetworkHierarchyRequestBus overrides.
//! @{
bool IsHierarchyEnabled() const override;
bool IsHierarchicalChild() const override;
bool IsHierarchicalRoot() const override { return false; }
AZ::Entity* GetHierarchicalRoot() const override;
AZStd::vector<AZ::Entity*> GetHierarchicalEntities() const override;
void BindNetworkHierarchyChangedEventHandler(NetworkHierarchyChangedEvent::Handler& handler) override;
void BindNetworkHierarchyLeaveEventHandler(NetworkHierarchyLeaveEvent::Handler& handler) override;
//! @}
protected:
//! Used by @NetworkHierarchyRootComponent
void SetTopLevelHierarchyRootEntity(AZ::Entity* hierarchyRoot);
private:
AZ::ChildChangedEvent::Handler m_childChangedHandler;
AZ::ParentChangedEvent::Handler m_parentChangedHandler;
void OnChildChanged(AZ::ChildChangeType type, AZ::EntityId child);
void OnParentChanged(AZ::EntityId oldParent, AZ::EntityId parent);
//! Points to the top level root.
AZ::Entity* m_rootEntity = nullptr;
AZ::Event<NetEntityId>::Handler m_hierarchyRootNetIdChanged;
void OnHierarchyRootNetIdChanged(NetEntityId rootNetId);
NetworkHierarchyChangedEvent m_networkHierarchyChangedEvent;
NetworkHierarchyLeaveEvent m_networkHierarchyLeaveEvent;
//! Set to false when deactivating or otherwise not to be included in hierarchy considerations.
bool m_isHierarchyEnabled = true;
void NotifyChildrenHierarchyDisbanded();
};
}
@@ -0,0 +1,100 @@
/*
* 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 <AzCore/Component/TransformBus.h>
#include <Multiplayer/Components/NetworkHierarchyBus.h>
#include <Source/AutoGen/NetworkHierarchyRootComponent.AutoComponent.h>
namespace Multiplayer
{
//! @class NetworkHierarchyRootComponent
//! @brief Component that declares the top level entity of a network hierarchy.
/*
* Call @GetHierarchicalEntities to get the list of hierarchical entities.
* A network hierarchy is meant to be a small group of entities. You can control the maximum supported size of
* a network hierarchy by modifying CVar @bg_hierarchyEntityMaxLimit.
*
* A root component marks either a top most root of a hierarchy, or an inner root of an attach hierarchy.
*/
class NetworkHierarchyRootComponent final
: public NetworkHierarchyRootComponentBase
, public NetworkHierarchyRequestBus::Handler
{
friend class NetworkHierarchyChildComponent;
public:
AZ_MULTIPLAYER_COMPONENT(Multiplayer::NetworkHierarchyRootComponent, s_networkHierarchyRootComponentConcreteUuid, Multiplayer::NetworkHierarchyRootComponentBase);
static void Reflect(AZ::ReflectContext* context);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
NetworkHierarchyRootComponent();
//! NetworkHierarchyRootComponentBase overrides.
//! @{
void OnInit() override;
void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
//! @}
//! NetworkHierarchyRequestBus overrides.
//! @{
bool IsHierarchyEnabled() const override;
bool IsHierarchicalRoot() const override;
bool IsHierarchicalChild() const override;
AZStd::vector<AZ::Entity*> GetHierarchicalEntities() const override;
AZ::Entity* GetHierarchicalRoot() const override;
void BindNetworkHierarchyChangedEventHandler(NetworkHierarchyChangedEvent::Handler& handler) override;
void BindNetworkHierarchyLeaveEventHandler(NetworkHierarchyLeaveEvent::Handler& handler) override;
//! @}
protected:
void SetTopLevelHierarchyRootEntity(AZ::Entity* hierarchyRoot);
private:
AZ::ChildChangedEvent::Handler m_childChangedHandler;
AZ::ParentChangedEvent::Handler m_parentChangedHandler;
void OnChildChanged(AZ::ChildChangeType type, AZ::EntityId child);
void OnParentChanged(AZ::EntityId oldParent, AZ::EntityId parent);
NetworkHierarchyChangedEvent m_networkHierarchyChangedEvent;
NetworkHierarchyLeaveEvent m_networkHierarchyLeaveEvent;
//! Points to the top level root, if this root is an inner root in this hierarchy.
AZ::Entity* m_rootEntity = nullptr;
AZStd::vector<AZ::Entity*> m_hierarchicalEntities;
//! Rebuilds hierarchy starting from this root component's entity.
void RebuildHierarchy();
//! @param underEntity Walk the child entities that belong to @underEntity and consider adding them to the hierarchy
//! @param currentEntityCount The total number of entities in the hierarchy prior to calling this method,
//! used to avoid adding too many entities to the hierarchy while walking recursively the relevant entities.
//! @currentEntityCount will be modified to reflect the total entity count upon completion of this method.
//! @returns false if an attempt was made to go beyond the maximum supported hierarchy size, true otherwise
bool RecursiveAttachHierarchicalEntities(AZ::EntityId underEntity, uint32_t& currentEntityCount);
//! @param entity Add the child entity and any of its relevant children to the hierarchy
//! @param currentEntityCount The total number of entities in the hierarchy prior to calling this method,
//! used to avoid adding too many entities to the hierarchy while walking recursively the relevant entities.
//! @currentEntityCount will be modified to reflect the total entity count upon completion of this method.
//! @returns false if an attempt was made to go beyond the maximum supported hierarchy size, true otherwise
bool RecursiveAttachHierarchicalChild(AZ::EntityId entity, uint32_t& currentEntityCount);
void SetRootForEntity(AZ::Entity* root, const AZ::Entity* childEntity);
//! Set to false when deactivating or otherwise not to be included in hierarchy considerations.
bool m_isHierarchyEnabled = true;
};
}
@@ -1,5 +1,6 @@
/*
* 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.
* 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
*
@@ -31,9 +31,11 @@ namespace Multiplayer
private:
void OnPreRender(float deltaTime);
void OnCorrection();
void OnParentChanged(NetEntityId parentId);
EntityPreRenderEvent::Handler m_entityPreRenderEventHandler;
EntityCorrectionEvent::Handler m_entityCorrectionEventHandler;
AZ::Event<NetEntityId>::Handler m_parentChangedEventHandler;
Multiplayer::HostFrameId m_targetHostFrameId = HostFrameId(0);
};
@@ -49,7 +51,9 @@ namespace Multiplayer
private:
void OnTransformChangedEvent(const AZ::Transform& worldTm);
void OnParentIdChangedEvent(AZ::EntityId oldParent, AZ::EntityId newParent);
AZ::TransformChangedEvent::Handler m_transformChangedHandler;
AZ::ParentChangedEvent::Handler m_parentIdChangedHandler;
};
}
@@ -162,9 +162,21 @@ namespace Multiplayer
//! @param entityFilter non-owning pointer, the caller is responsible for memory management.
virtual void SetFilterEntityManager(IFilterEntityManager* entityFilter) = 0;
//! @return pointer to the user-defined filtering manager of entities. By default, this isn't set and returns nullptr.
//! Returns a pointer to the user-defined filtering manager of entities.
//! @return pointer to the filtered entity manager, or nullptr if not set
virtual IFilterEntityManager* GetFilterEntityManager() = 0;
//! Enables or disables automatic instantiation of netbound entities.
//! This setting is controlled by the networking layer and should not be touched
//! If enabled, netbound entities will instantiate as spawnables are loaded into the game world, generally true for the server
//! If disabled, netbound entities will only stream from a host, always true for a client
//! @param value boolean value controlling netbound entity instantiation behaviour
virtual void SetShouldSpawnNetworkEntities(bool value) = 0;
//! Retrieves the current network entity instantiation behaviour.
//! @return boolean true if netbound entities should be auto instantiated, false if not
virtual bool GetShouldSpawnNetworkEntities() const = 0;
//! Retrieve the stats object bound to this multiplayer instance.
//! @return the stats object bound to this multiplayer instance
MultiplayerStats& GetStats() { return m_stats; }
@@ -36,7 +36,7 @@ namespace Multiplayer
{
public:
EntityReplicator(EntityReplicationManager& replicationManager, AzNetworking::IConnection* connection, NetEntityRole remoteNetworkRole, const ConstNetworkEntityHandle& entityHandle);
virtual ~EntityReplicator();
~EntityReplicator() override;
NetEntityRole GetBoundLocalNetworkRole() const;
NetEntityRole GetRemoteNetworkRole() const;
@@ -62,6 +62,8 @@ namespace Multiplayer
bool IsDeletionAcknowledged() const;
bool WasMigrated() const;
void SetWasMigrated(bool wasMigrated);
// If an entity is part of a network hierarchy then it is only ready to activate when its direct parent entity is active.
bool IsReadyToActivate() const;
NetworkEntityUpdateMessage GenerateUpdatePacket();
@@ -13,6 +13,7 @@
#include <AzCore/Component/Entity.h>
#include <AzCore/EBus/Event.h>
#include <AzCore/Asset/AssetCommon.h>
#include <AzFramework/Spawnable/SpawnableEntitiesInterface.h>
namespace Multiplayer
{
@@ -89,6 +90,15 @@ namespace Multiplayer
const AZ::Transform& transform
) = 0;
//! Requests a network spawnable to instantiate at a given transform
//! This is an async function. The instantiated entities are not available immediately but will be constructed by the spawnable system
//! The spawnable ticket has to be kept for the whole lifetime of the entities
//! @param netSpawnable the network spawnable to spawn
//! @param transform the transform where the spawnable should be spawned
//! @return the ticket for managing the spawned entities
[[nodiscard]] virtual AZStd::unique_ptr<AzFramework::EntitySpawnTicket> RequestNetSpawnableInstantiation(
const AZ::Data::Asset<AzFramework::Spawnable>& netSpawnable, const AZ::Transform& transform) = 0;
//! Configures new networked entity
//! @param netEntity the entity to setup
//! @param prefabEntryId the name of the spawnable the entity originated from