Entity migrations now totally functional again, plus some fixes to network rigid bodies to make them work properly as they migrate around
Signed-off-by: kberg-amzn <karlberg@amazon.com>
This commit is contained in:
+13
-6
@@ -45,6 +45,7 @@ namespace Multiplayer
|
||||
, m_clearRemovedReplicators([this]() { ClearRemovedReplicators(); }, AZ::Name("EntityReplicationManager::ClearRemovedReplicators"))
|
||||
, m_updateWindow([this]() { UpdateWindow(); }, AZ::Name("EntityReplicationManager::UpdateWindow"))
|
||||
, m_entityExitDomainEventHandler([this](const ConstNetworkEntityHandle& entityHandle) { OnEntityExitDomain(entityHandle); })
|
||||
, m_notifyEntityMigrationHandler([this](const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId) { OnPostEntityMigration(entityHandle, remoteHostId); })
|
||||
{
|
||||
// Our max payload size is whatever is passed in, minus room for a udp packetheader
|
||||
m_maxPayloadSize = connection.GetConnectionMtu() - UdpPacketHeaderSerializeSize - ReplicationManagerPacketOverhead;
|
||||
@@ -60,6 +61,8 @@ namespace Multiplayer
|
||||
{
|
||||
networkEntityManager->AddEntityExitDomainHandler(m_entityExitDomainEventHandler);
|
||||
}
|
||||
|
||||
GetMultiplayer()->AddNotifyEntityMigrationEventHandler(m_notifyEntityMigrationHandler);
|
||||
}
|
||||
|
||||
void EntityReplicationManager::SetRemoteHostId(const HostId& hostId)
|
||||
@@ -355,8 +358,9 @@ namespace Multiplayer
|
||||
entityReplicator = GetEntityReplicator(entityHandle);
|
||||
if (entityReplicator)
|
||||
{
|
||||
// Check if we changed our remote role - this can happen during server entity migration. After we migrate ownership to the new server, we hold onto our entity replicator until we are sure
|
||||
// the other side has received all the packets (and we haven't had to do resends). At this point, it is possible hear back from the remote side we migrated to on the old replicator prior to the timeout and cleanup on the old one
|
||||
// Check if we changed our remote role - this can happen during server entity migration.
|
||||
// Retain our replicator after migration until we are sure the other side has received all the packets (and we haven't had to do resends).
|
||||
// At this point, the remote host should inform us we've migrated prior to the timeout and cleanup of the old replicator
|
||||
const bool changedRemoteRole = (remoteNetworkRole != entityReplicator->GetRemoteNetworkRole());
|
||||
// Check if we've changed our bound local role - this can occur when we gain Autonomous or lose Autonomous on a client
|
||||
bool changedLocalRole(false);
|
||||
@@ -1068,12 +1072,12 @@ namespace Multiplayer
|
||||
return false;
|
||||
}
|
||||
|
||||
void EntityReplicationManager::SetEntityDomain(AZStd::unique_ptr<IEntityDomain> entityDomain)
|
||||
void EntityReplicationManager::SetRemoteEntityDomain(AZStd::unique_ptr<IEntityDomain> entityDomain)
|
||||
{
|
||||
m_remoteEntityDomain = AZStd::move(entityDomain);
|
||||
}
|
||||
|
||||
IEntityDomain* EntityReplicationManager::GetEntityDomain()
|
||||
IEntityDomain* EntityReplicationManager::GetRemoteEntityDomain()
|
||||
{
|
||||
return m_remoteEntityDomain.get();
|
||||
}
|
||||
@@ -1143,6 +1147,9 @@ namespace Multiplayer
|
||||
m_sendMigrateEntityEvent.Signal(m_connection, message);
|
||||
AZLOG(NET_RepDeletes, "Migration packet sent %u to remote host %s", netEntityId, GetRemoteHostId().GetString().c_str());
|
||||
|
||||
// Notify all other EntityReplicationManagers that this entity has migrated so they can adjust their own replicators given our new proxy status
|
||||
GetMultiplayer()->SendNotifyEntityMigrationEvent(entityHandle, GetRemoteHostId());
|
||||
|
||||
// Immediately add a new replicator so that we catch RPC invocations, the remote side will make us a new one, and then remove us if needs be
|
||||
AddEntityReplicator(entityHandle, NetEntityRole::Authority);
|
||||
}
|
||||
@@ -1206,11 +1213,11 @@ namespace Multiplayer
|
||||
}
|
||||
}
|
||||
|
||||
void EntityReplicationManager::OnPostEntityMigration(const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId, [[maybe_unused]] AzNetworking::ConnectionId connectionId)
|
||||
void EntityReplicationManager::OnPostEntityMigration(const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId)
|
||||
{
|
||||
if (remoteHostId == GetRemoteHostId())
|
||||
{
|
||||
// don't handle self sent messages
|
||||
// Don't handle self sent messages
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Multiplayer
|
||||
{
|
||||
if (auto localEnt = m_entityHandle.GetEntity())
|
||||
{
|
||||
m_netBindComponent = localEnt->FindComponent<NetBindComponent>();
|
||||
m_netBindComponent = m_entityHandle.GetNetBindComponent();
|
||||
m_boundLocalNetworkRole = m_netBindComponent->GetNetEntityRole();
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ namespace Multiplayer
|
||||
m_entityHandle = entityHandle;
|
||||
if (auto localEntity = m_entityHandle.GetEntity())
|
||||
{
|
||||
m_netBindComponent = localEntity->FindComponent<NetBindComponent>();
|
||||
m_netBindComponent = m_entityHandle.GetNetBindComponent();
|
||||
AZ_Assert(m_netBindComponent, "No Multiplayer::NetBindComponent");
|
||||
m_boundLocalNetworkRole = m_netBindComponent->GetNetEntityRole();
|
||||
SetPrefabEntityId(m_netBindComponent->GetPrefabEntityId());
|
||||
@@ -125,7 +125,8 @@ namespace Multiplayer
|
||||
!RemoteManagerOwnsEntityLifetime() ? PropertyPublisher::OwnsLifetime::True : PropertyPublisher::OwnsLifetime::False,
|
||||
m_netBindComponent,
|
||||
*m_connection
|
||||
);
|
||||
);
|
||||
m_onEntityDirtiedHandler.Disconnect();
|
||||
m_netBindComponent->AddEntityDirtiedEventHandler(m_onEntityDirtiedHandler);
|
||||
}
|
||||
else
|
||||
@@ -146,8 +147,9 @@ namespace Multiplayer
|
||||
// Prepare event handlers
|
||||
if (auto localEntity = m_entityHandle.GetEntity())
|
||||
{
|
||||
NetBindComponent* netBindComponent = localEntity->FindComponent<NetBindComponent>();
|
||||
NetBindComponent* netBindComponent = m_entityHandle.GetNetBindComponent();
|
||||
AZ_Assert(netBindComponent, "No Multiplayer::NetBindComponent");
|
||||
m_onEntityStopHandler.Disconnect();
|
||||
netBindComponent->AddEntityStopEventHandler(m_onEntityStopHandler);
|
||||
AttachRPCHandlers();
|
||||
}
|
||||
@@ -168,7 +170,7 @@ namespace Multiplayer
|
||||
|
||||
if (auto localEntity = m_entityHandle.GetEntity())
|
||||
{
|
||||
NetBindComponent* netBindComponent = localEntity->FindComponent<NetBindComponent>();
|
||||
NetBindComponent* netBindComponent = m_entityHandle.GetNetBindComponent();
|
||||
AZ_Assert(netBindComponent, "No Multiplayer::NetBindComponent");
|
||||
|
||||
switch (GetBoundLocalNetworkRole())
|
||||
@@ -479,10 +481,10 @@ namespace Multiplayer
|
||||
}
|
||||
|
||||
NetBindComponent* netBindComponent = GetNetBindComponent();
|
||||
const bool sendSliceName = !m_propertyPublisher->IsRemoteReplicatorEstablished();
|
||||
//const bool sendSliceName = !m_propertyPublisher->IsRemoteReplicatorEstablished();
|
||||
|
||||
NetworkEntityUpdateMessage updateMessage(GetRemoteNetworkRole(), GetEntityHandle().GetNetEntityId());
|
||||
if (sendSliceName)
|
||||
//if (sendSliceName)
|
||||
{
|
||||
updateMessage.SetPrefabEntityId(netBindComponent->GetPrefabEntityId());
|
||||
}
|
||||
|
||||
@@ -20,6 +20,11 @@ namespace Multiplayer
|
||||
: m_entity(entity)
|
||||
, m_networkEntityTracker(networkEntityTracker)
|
||||
{
|
||||
if (m_networkEntityTracker == nullptr)
|
||||
{
|
||||
m_networkEntityTracker = GetNetworkEntityTracker();
|
||||
}
|
||||
|
||||
if (m_networkEntityTracker)
|
||||
{
|
||||
m_changeDirty = m_networkEntityTracker->GetChangeDirty(m_entity);
|
||||
@@ -28,12 +33,10 @@ namespace Multiplayer
|
||||
if (entity)
|
||||
{
|
||||
AZ_Assert(networkEntityTracker, "NetworkEntityTracker is not valid");
|
||||
NetBindComponent* netBindComponent = m_entity->template FindComponent<NetBindComponent>();
|
||||
if (netBindComponent != nullptr)
|
||||
m_netBindComponent = networkEntityTracker->GetNetBindComponent(entity);
|
||||
if (m_netBindComponent != nullptr)
|
||||
{
|
||||
AZ_Assert(netBindComponent, "No Multiplayer::NetBindComponent");
|
||||
m_netBindComponent = netBindComponent;
|
||||
m_netEntityId = netBindComponent->GetNetEntityId();
|
||||
m_netEntityId = m_netBindComponent->GetNetEntityId();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -42,30 +45,6 @@ namespace Multiplayer
|
||||
}
|
||||
}
|
||||
|
||||
ConstNetworkEntityHandle::ConstNetworkEntityHandle(AZ::Entity* entity, NetEntityId netEntityId, const NetworkEntityTracker* networkEntityTracker)
|
||||
: m_entity(entity)
|
||||
, m_netEntityId(netEntityId)
|
||||
, m_networkEntityTracker(networkEntityTracker)
|
||||
{
|
||||
if (m_networkEntityTracker)
|
||||
{
|
||||
m_changeDirty = m_networkEntityTracker->GetChangeDirty(m_entity);
|
||||
}
|
||||
}
|
||||
|
||||
ConstNetworkEntityHandle::ConstNetworkEntityHandle(NetBindComponent* netBindComponent, const NetworkEntityTracker* networkEntityTracker)
|
||||
: m_entity(netBindComponent->GetEntity())
|
||||
, m_netBindComponent(netBindComponent)
|
||||
, m_networkEntityTracker(networkEntityTracker)
|
||||
, m_netEntityId(netBindComponent->GetNetEntityId())
|
||||
{
|
||||
if (m_networkEntityTracker)
|
||||
{
|
||||
m_changeDirty = m_networkEntityTracker->GetChangeDirty(m_entity);
|
||||
}
|
||||
AZ_Assert(networkEntityTracker, "NetworkEntityTracker is not valid");
|
||||
}
|
||||
|
||||
bool ConstNetworkEntityHandle::Exists() const
|
||||
{
|
||||
if (!m_networkEntityTracker)
|
||||
@@ -151,7 +130,7 @@ namespace Multiplayer
|
||||
}
|
||||
if (m_netBindComponent == nullptr)
|
||||
{
|
||||
m_netBindComponent = m_entity->template FindComponent<NetBindComponent>();
|
||||
m_netBindComponent = m_networkEntityTracker->GetNetBindComponent(m_entity);
|
||||
}
|
||||
return m_netBindComponent;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
#include <AzFramework/Entity/EntityContextBus.h>
|
||||
#include <AzFramework/Entity/GameEntityContextBus.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <AzFramework/Visibility/EntityBoundsUnionBus.h>
|
||||
#include <AzFramework/Spawnable/SpawnableEntitiesInterface.h>
|
||||
#include <Multiplayer/IMultiplayer.h>
|
||||
#include <Multiplayer/Components/NetBindComponent.h>
|
||||
@@ -46,6 +48,7 @@ namespace Multiplayer
|
||||
m_hostId = hostId;
|
||||
m_entityDomain = AZStd::move(entityDomain);
|
||||
m_updateEntityDomainEvent.Enqueue(net_EntityDomainUpdateMs, true);
|
||||
m_entityDomain->ActivateTracking(m_ownedEntities);
|
||||
}
|
||||
|
||||
bool NetworkEntityManager::IsInitialized() const
|
||||
@@ -96,7 +99,7 @@ namespace Multiplayer
|
||||
NetworkEntityHandle NetworkEntityManager::AddEntityToEntityMap(NetEntityId netEntityId, AZ::Entity* entity)
|
||||
{
|
||||
m_networkEntityTracker.Add(netEntityId, entity);
|
||||
return NetworkEntityHandle(entity, netEntityId, &m_networkEntityTracker);
|
||||
return NetworkEntityHandle(entity, &m_networkEntityTracker);
|
||||
}
|
||||
|
||||
void NetworkEntityManager::MarkForRemoval(const ConstNetworkEntityHandle& entityHandle)
|
||||
@@ -212,6 +215,29 @@ namespace Multiplayer
|
||||
m_localDeferredRpcMessages.emplace_back(AZStd::move(message));
|
||||
}
|
||||
|
||||
void NetworkEntityManager::DebugDraw() const
|
||||
{
|
||||
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
||||
AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, AzFramework::g_defaultSceneEntityDebugDisplayId);
|
||||
AzFramework::DebugDisplayRequests* debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
||||
|
||||
for (NetworkEntityTracker::const_iterator it = m_networkEntityTracker.begin(); it != m_networkEntityTracker.end(); ++it)
|
||||
{
|
||||
AZ::Entity* entity = it->second;
|
||||
NetBindComponent* netBindComponent = m_networkEntityTracker.GetNetBindComponent(entity);
|
||||
if (netBindComponent->GetNetEntityRole() == NetEntityRole::Authority)
|
||||
{
|
||||
const AZ::Aabb entityBounds = AZ::Interface<AzFramework::IEntityBoundsUnion>::Get()->GetEntityWorldBoundsUnion(entity->GetId());
|
||||
debugDisplay->DrawWireBox(entityBounds.GetMin(), entityBounds.GetMax());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_entityDomain != nullptr)
|
||||
{
|
||||
m_entityDomain->DebugDraw();
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkEntityManager::DispatchLocalDeferredRpcMessages()
|
||||
{
|
||||
for (NetworkEntityRpcMessage& rpcMessage : m_localDeferredRpcMessages)
|
||||
@@ -219,7 +245,7 @@ namespace Multiplayer
|
||||
AZ::Entity* entity = m_networkEntityTracker.GetRaw(rpcMessage.GetEntityId());
|
||||
if (entity != nullptr)
|
||||
{
|
||||
NetBindComponent* netBindComponent = entity->FindComponent<NetBindComponent>();
|
||||
NetBindComponent* netBindComponent = m_networkEntityTracker.GetNetBindComponent(entity);
|
||||
AZ_Assert(netBindComponent != nullptr, "Attempting to send an RPC to an entity with no NetBindComponent");
|
||||
netBindComponent->HandleRpcMessage(nullptr, NetEntityRole::Server, rpcMessage);
|
||||
}
|
||||
@@ -234,9 +260,8 @@ namespace Multiplayer
|
||||
return;
|
||||
}
|
||||
|
||||
m_entitiesNotInDomain.clear();
|
||||
m_entityDomain->RetrieveEntitiesNotInDomain(m_entitiesNotInDomain);
|
||||
for (NetEntityId exitingId : m_entitiesNotInDomain)
|
||||
const IEntityDomain::EntitiesNotInDomain& entitiesNotInDomain = m_entityDomain->RetrieveEntitiesNotInDomain();
|
||||
for (NetEntityId exitingId : entitiesNotInDomain)
|
||||
{
|
||||
OnEntityExitDomain(exitingId);
|
||||
}
|
||||
@@ -247,18 +272,6 @@ namespace Multiplayer
|
||||
bool safeToExit = true;
|
||||
NetworkEntityHandle entityHandle = m_networkEntityTracker.Get(entityId);
|
||||
|
||||
// ClientAutonomous entities need special handling here. When we migrate a player's entity the player's client must tell the new server which
|
||||
// entity they were controlling. If we tell them to migrate before they know which entity they control it results in them requesting a new entity
|
||||
// from the new server, resulting in an orphaned PlayerChar. PlayerControllerComponentServerAuthority::PlayerClientHasControlledEntity()
|
||||
// will tell us whether the client sent an RPC acknowledging that they now know which entity is theirs.
|
||||
if (AZ::Entity* entity = entityHandle.GetEntity())
|
||||
{
|
||||
//if (PlayerComponent::Authority* playerController = FindController<PlayerComponent::Authority>(nonConstExitingEntityPtr))
|
||||
//{
|
||||
// safeToExit = playerController->PlayerClientHasControlledEntity();
|
||||
//}
|
||||
}
|
||||
|
||||
// We also need special handling for the EntityHierarchyComponent as well, since related entities need to be migrated together
|
||||
//auto* hierarchyController = FindController<EntityHierarchyComponent::Authority>(nonConstExitingEntityPtr);
|
||||
//if (hierarchyController)
|
||||
@@ -338,6 +351,7 @@ namespace Multiplayer
|
||||
|
||||
originalToCloneIdMap[originalEntity->GetId()] = clone->GetId();
|
||||
|
||||
// Can't use NetworkEntityTracker to do the lookup since the entity has not activated yet
|
||||
NetBindComponent* netBindComponent = clone->FindComponent<NetBindComponent>();
|
||||
if (netBindComponent != nullptr)
|
||||
{
|
||||
|
||||
@@ -62,9 +62,7 @@ namespace Multiplayer
|
||||
|
||||
AZStd::unique_ptr<AzFramework::EntitySpawnTicket> RequestNetSpawnableInstantiation(
|
||||
const AZ::Data::Asset<AzFramework::Spawnable>& netSpawnable, const AZ::Transform& transform) override;
|
||||
|
||||
void SetupNetEntity(AZ::Entity* netEntity, PrefabEntityId prefabEntityId, NetEntityRole netEntityRole) override;
|
||||
|
||||
uint32_t GetEntityCount() const override;
|
||||
NetworkEntityHandle AddEntityToEntityMap(NetEntityId netEntityId, AZ::Entity* entity) override;
|
||||
void MarkForRemoval(const ConstNetworkEntityHandle& entityHandle) override;
|
||||
@@ -81,11 +79,13 @@ namespace Multiplayer
|
||||
void NotifyControllersActivated(const ConstNetworkEntityHandle& entityHandle, EntityIsMigrating entityIsMigrating) override;
|
||||
void NotifyControllersDeactivated(const ConstNetworkEntityHandle& entityHandle, EntityIsMigrating entityIsMigrating) override;
|
||||
void HandleLocalRpcMessage(NetworkEntityRpcMessage& message) override;
|
||||
void DebugDraw() const override;
|
||||
//! @}
|
||||
|
||||
void DispatchLocalDeferredRpcMessages();
|
||||
void UpdateEntityDomain();
|
||||
void OnEntityExitDomain(NetEntityId entityId);
|
||||
|
||||
//! RootSpawnableNotificationBus
|
||||
//! @{
|
||||
void OnRootSpawnableAssigned(AZ::Data::Asset<AzFramework::Spawnable> rootSpawnable, uint32_t generation) override;
|
||||
@@ -105,7 +105,6 @@ namespace Multiplayer
|
||||
AZStd::unique_ptr<IEntityDomain> m_entityDomain;
|
||||
AZ::ScheduledEvent m_updateEntityDomainEvent;
|
||||
|
||||
IEntityDomain::EntitiesNotInDomain m_entitiesNotInDomain;
|
||||
OwnedEntitySet m_ownedEntities;
|
||||
|
||||
EntityExitDomainEvent m_entityExitDomainEvent;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <Source/NetworkEntity/NetworkEntityTracker.h>
|
||||
#include <Multiplayer/NetworkEntity/NetworkEntityHandle.h>
|
||||
#include <Multiplayer/Components/NetBindComponent.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Console/ILogger.h>
|
||||
|
||||
@@ -21,16 +22,26 @@ namespace Multiplayer
|
||||
m_netEntityIdMap[entity->GetId()] = netEntityId;
|
||||
}
|
||||
|
||||
void NetworkEntityTracker::RegisterNetBindComponent(AZ::Entity* entity, NetBindComponent* component)
|
||||
{
|
||||
m_netBindingMap[entity] = component;
|
||||
}
|
||||
|
||||
void NetworkEntityTracker::UnregisterNetBindComponent(NetBindComponent* component)
|
||||
{
|
||||
m_netBindingMap.erase(component->GetEntity());
|
||||
}
|
||||
|
||||
NetworkEntityHandle NetworkEntityTracker::Get(NetEntityId netEntityId)
|
||||
{
|
||||
AZ::Entity* entity = GetRaw(netEntityId);
|
||||
return NetworkEntityHandle(entity, netEntityId, this);
|
||||
return NetworkEntityHandle(entity, this);
|
||||
}
|
||||
|
||||
ConstNetworkEntityHandle NetworkEntityTracker::Get(NetEntityId netEntityId) const
|
||||
{
|
||||
AZ::Entity* entity = GetRaw(netEntityId);
|
||||
return ConstNetworkEntityHandle(entity, netEntityId, this);
|
||||
return ConstNetworkEntityHandle(entity, this);
|
||||
}
|
||||
|
||||
NetEntityId NetworkEntityTracker::Get(const AZ::EntityId& entityId) const
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
class NetBindComponent;
|
||||
|
||||
//! @class NetworkEntityTracker
|
||||
//! @brief The responsibly of this class is to allow entity netEntityId's to be looked up.
|
||||
class NetworkEntityTracker
|
||||
@@ -23,16 +25,26 @@ namespace Multiplayer
|
||||
|
||||
using EntityMap = AZStd::unordered_map<NetEntityId, AZ::Entity*>;
|
||||
using NetEntityIdMap = AZStd::unordered_map<AZ::EntityId, NetEntityId>;
|
||||
using NetBindingMap = AZStd::unordered_map<AZ::Entity*, NetBindComponent*>;
|
||||
using iterator = EntityMap::iterator;
|
||||
using const_iterator = EntityMap::const_iterator;
|
||||
|
||||
NetworkEntityTracker() = default;
|
||||
|
||||
//! Adds a networked entity to the tracker
|
||||
//! Adds a networked entity to the tracker.
|
||||
//! @param netEntityId the networkId of the entity to add
|
||||
//! @param entity pointer to the entity corresponding to the networkId
|
||||
void Add(NetEntityId netEntityId, AZ::Entity* entity);
|
||||
|
||||
//! Registers a new NetBindComponent with the NetworkEntityTracker.
|
||||
//! @param entity pointer to the entity we are registering the NetBindComponent for
|
||||
//! @param component pointer to the NetBindComponent being registered
|
||||
void RegisterNetBindComponent(AZ::Entity* entity, NetBindComponent* component);
|
||||
|
||||
//! Unregisters a NetBindComponent from the NetworkEntityTracker.
|
||||
//! @param component pointer to the NetBindComponent being removed
|
||||
void UnregisterNetBindComponent(NetBindComponent* component);
|
||||
|
||||
//! Returns an entity handle which can validate entity existence.
|
||||
NetworkEntityHandle Get(NetEntityId netEntityId);
|
||||
ConstNetworkEntityHandle Get(NetEntityId netEntityId) const;
|
||||
@@ -46,9 +58,14 @@ namespace Multiplayer
|
||||
//! Get a raw pointer of an entity.
|
||||
AZ::Entity *GetRaw(NetEntityId netEntityId) const;
|
||||
|
||||
//! Moves the given iterator out of the entity holder and returns the ptr
|
||||
//! Moves the given iterator out of the entity holder and returns the ptr.
|
||||
AZ::Entity *Move(EntityMap::iterator iter);
|
||||
|
||||
//! Retrieves the NetBindComponent for the provided AZ::Entity, nullptr if the entity does not have netbinding.
|
||||
//! @param entity pointer to the entity to retrieve the NetBindComponent for
|
||||
//! @return pointer to the entities NetBindComponent, or nullptr if the entity doesn't exist or does not have netbinding
|
||||
NetBindComponent* GetNetBindComponent(AZ::Entity* rawEntity) const;
|
||||
|
||||
//! Container overloads
|
||||
//!@{
|
||||
iterator begin();
|
||||
@@ -79,6 +96,7 @@ namespace Multiplayer
|
||||
|
||||
EntityMap m_entityMap;
|
||||
NetEntityIdMap m_netEntityIdMap;
|
||||
NetBindingMap m_netBindingMap;
|
||||
uint32_t m_deleteChangeDirty = 0;
|
||||
uint32_t m_addChangeDirty = 0;
|
||||
};
|
||||
|
||||
@@ -10,6 +10,16 @@
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
inline NetBindComponent* NetworkEntityTracker::GetNetBindComponent(AZ::Entity* rawEntity) const
|
||||
{
|
||||
auto found = m_netBindingMap.find(rawEntity);
|
||||
if (found != m_netBindingMap.end())
|
||||
{
|
||||
return found->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline NetworkEntityTracker::iterator NetworkEntityTracker::begin()
|
||||
{
|
||||
return m_entityMap.begin();
|
||||
|
||||
Reference in New Issue
Block a user