First pass for network hierarchy input processing
Signed-off-by: pereslav <pereslav@amazon.com>
This commit is contained in:
+3
-1
@@ -4,11 +4,13 @@
|
||||
Name="NetworkHierarchyRootComponent"
|
||||
Namespace="Multiplayer"
|
||||
OverrideComponent="true"
|
||||
OverrideController="false"
|
||||
OverrideController="true"
|
||||
OverrideInclude="Multiplayer/Components/NetworkHierarchyRootComponent.h"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<ComponentRelation Constraint="Required" HasController="true" Name="NetworkTransformComponent" Namespace="Multiplayer" Include="Multiplayer/Components/NetworkTransformComponent.h" />
|
||||
|
||||
<NetworkInput Type="AZStd::vector<NetworkSubInput>" Name="ChildInputs" Init="" />
|
||||
|
||||
<NetworkProperty Type="NetEntityId" Name="hierarchyRoot" Init="InvalidNetEntityId" ReplicateFrom="Authority" ReplicateTo="Client" IsRewindable="false" IsPredictable="false" IsPublic="true" Container="Object" ExposeToEditor="false" ExposeToScript="false" GenerateEventBindings="true" />
|
||||
</Component>
|
||||
|
||||
@@ -139,6 +139,11 @@ namespace Multiplayer
|
||||
return m_hierarchicalEntities;
|
||||
}
|
||||
|
||||
const AZStd::vector<AZ::Entity*>& NetworkHierarchyRootComponent::GetHierarchicalEntitiesRef() const
|
||||
{
|
||||
return m_hierarchicalEntities;
|
||||
}
|
||||
|
||||
AZ::Entity* NetworkHierarchyRootComponent::GetHierarchicalRoot() const
|
||||
{
|
||||
if (m_rootEntity)
|
||||
@@ -326,4 +331,99 @@ namespace Multiplayer
|
||||
RebuildHierarchy();
|
||||
}
|
||||
}
|
||||
|
||||
NetworkHierarchyRootComponentController::NetworkHierarchyRootComponentController(NetworkHierarchyRootComponent& parent)
|
||||
: NetworkHierarchyRootComponentControllerBase(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void NetworkHierarchyRootComponentController::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void NetworkHierarchyRootComponentController::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Multiplayer::MultiplayerController::InputPriorityOrder NetworkHierarchyRootComponentController::GetInputOrder() const
|
||||
{
|
||||
return Multiplayer::MultiplayerController::InputPriorityOrder::SubEntities;
|
||||
}
|
||||
|
||||
void NetworkHierarchyRootComponentController::CreateInput(Multiplayer::NetworkInput& input, float deltaTime)
|
||||
{
|
||||
NetworkHierarchyRootComponent& component = GetParent();
|
||||
if(!component.IsHierarchicalRoot())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const AZStd::vector<AZ::Entity*>& entities = component.GetHierarchicalEntitiesRef();
|
||||
|
||||
auto* networkInput = input.FindComponentInput<NetworkHierarchyRootComponentNetworkInput>();
|
||||
networkInput->m_childInputs.clear();
|
||||
networkInput->m_childInputs.reserve(entities.size());
|
||||
|
||||
for (AZ::Entity* child : entities)
|
||||
{
|
||||
if(child == component.GetEntity())
|
||||
{
|
||||
return; // Avoid infinite recursion
|
||||
}
|
||||
|
||||
auto* netComp = child->FindComponent<NetBindComponent>();
|
||||
AZ_Assert(netComp, "No NetSystemComponent, this should be impossible");
|
||||
// Validate we still have a controller and we aren't in the middle of removing them
|
||||
if (netComp->HasController())
|
||||
{
|
||||
ConstNetworkEntityHandle childEntityHandle = netComp->GetEntityHandle();
|
||||
NetworkSubInput subInput;
|
||||
subInput.Attach(childEntityHandle);
|
||||
subInput.GetNetworkInput().SetClientInputId(input.GetClientInputId());
|
||||
|
||||
netComp->CreateInput(subInput.GetNetworkInput(), deltaTime);
|
||||
|
||||
// make sure our input sub commands have the same time as the original
|
||||
subInput.GetNetworkInput().SetClientInputId(input.GetClientInputId());
|
||||
networkInput->m_childInputs.emplace_back(subInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkHierarchyRootComponentController::ProcessInput(Multiplayer::NetworkInput& input, float deltaTime)
|
||||
{
|
||||
// Prevent replaying process input commands for child entities that weren't part of the hierarchy at that time
|
||||
//if (!m_firstProcessInputOccurred)
|
||||
//{
|
||||
// m_firstProcessInputOccurred = true;
|
||||
// m_firstProcessInputTime = input.GetInputId().GetGameTimePoint();
|
||||
//}
|
||||
//else if (m_firstProcessInputTime > input.GetInputId().GetGameTimePoint())
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
if (auto* networkInput = input.FindComponentInput<NetworkHierarchyRootComponentNetworkInput>())
|
||||
{
|
||||
for (NetworkSubInput& subInput : networkInput->m_childInputs)
|
||||
{
|
||||
const ConstNetworkEntityHandle& childEntity = subInput.GetOwner();
|
||||
if (auto* localChild = childEntity.GetEntity())
|
||||
{
|
||||
auto* netComp = localChild->FindComponent<NetBindComponent>();
|
||||
AZ_Assert(netComp, "No NetSystemComponent, this should be impossible");
|
||||
// We do not rewind entity role changes, so make sure we are the correct role prior to processing
|
||||
if (netComp->HasController())
|
||||
{
|
||||
subInput.GetNetworkInput().SetClientInputId(input.GetClientInputId());
|
||||
netComp->ProcessInput(subInput.GetNetworkInput(), deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -188,4 +188,53 @@ namespace Multiplayer
|
||||
}
|
||||
m_wasAttached = rhs.m_wasAttached;
|
||||
}
|
||||
|
||||
NetworkSubInput::NetworkSubInput(const ConstNetworkEntityHandle& entityHandle)
|
||||
: m_owner(entityHandle)
|
||||
{
|
||||
Attach(m_owner);
|
||||
}
|
||||
|
||||
void NetworkSubInput::Attach(const ConstNetworkEntityHandle& entityHandle)
|
||||
{
|
||||
m_owner = entityHandle;
|
||||
if (auto* localEnt = entityHandle.GetEntity())
|
||||
{
|
||||
NetBindComponent* netBindComponent = localEnt->FindComponent<NetBindComponent>();
|
||||
if (netBindComponent)
|
||||
{
|
||||
m_networkInput.AttachNetBindComponent(netBindComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ConstNetworkEntityHandle& NetworkSubInput::GetOwner() const
|
||||
{
|
||||
return m_owner;
|
||||
}
|
||||
|
||||
NetworkInput& NetworkSubInput::GetNetworkInput()
|
||||
{
|
||||
return m_networkInput;
|
||||
}
|
||||
|
||||
const NetworkInput& NetworkSubInput::GetNetworkInput() const
|
||||
{
|
||||
return m_networkInput;
|
||||
}
|
||||
|
||||
bool NetworkSubInput::Serialize(AzNetworking::ISerializer& serializer)
|
||||
{
|
||||
NetEntityId tmpId = m_owner.GetNetEntityId();
|
||||
serializer.Serialize(tmpId, "OwnerId");
|
||||
|
||||
if (serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject)
|
||||
{
|
||||
m_owner = AZ::Interface<INetworkEntityManager>::Get()->GetEntity(tmpId);
|
||||
}
|
||||
|
||||
serializer.Serialize(m_networkInput, "NetInput");
|
||||
return serializer.IsValid();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user