Fixed crash in ConstEntityHandle. Added hierarchical correction data serialization

Signed-off-by: pereslav <pereslav@amazon.com>
This commit is contained in:
pereslav
2021-10-08 21:19:22 +01:00
parent cb53389004
commit 0c2c042fde
6 changed files with 51 additions and 8 deletions
@@ -71,6 +71,8 @@ namespace Multiplayer
void UpdateAutonomous(AZ::TimeMs deltaTimeMs);
void UpdateBankedTime(AZ::TimeMs deltaTimeMs);
bool SerializeEntityCorrection(AzNetworking::ISerializer& serializer);
using StateHistoryItem = AZStd::unique_ptr<AzNetworking::StringifySerializer>;
AZStd::map<ClientInputId, StateHistoryItem> m_predictiveStateHistory;
@@ -59,6 +59,8 @@ namespace Multiplayer
void BindNetworkHierarchyLeaveEventHandler(NetworkHierarchyLeaveEvent::Handler& handler) override;
//! @}
bool SerializeEntityCorrection(AzNetworking::ISerializer& serializer);
protected:
void SetTopLevelHierarchyRootEntity(AZ::Entity* hierarchyRoot);
@@ -9,6 +9,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ComponentRelation Constraint="Weak" HasController="true" Name="NetworkTransformComponent" Namespace="Multiplayer" Include="Multiplayer/Components/NetworkTransformComponent.h" />
<ComponentRelation Constraint="Weak" HasController="true" Name="NetworkHierarchyRootComponent" Namespace="Multiplayer" Include="Multiplayer/Components/NetworkHierarchyRootComponent.h" />
<Include File="Multiplayer/MultiplayerTypes.h"/>
<Include File="Multiplayer/NetworkInput/NetworkInput.h"/>
@@ -14,6 +14,7 @@
#include <AzNetworking/Serialization/NetworkOutputSerializer.h>
#include <AzNetworking/Serialization/StringifySerializer.h>
#include <AzNetworking/Serialization/TrackChangedSerializer.h>
#include <Multiplayer/Components/NetworkHierarchyRootComponent.h>
namespace Multiplayer
{
@@ -211,7 +212,7 @@ namespace Multiplayer
m_lastCorrectionSentTimeMs = currentTimeMs;
AzNetworking::HashSerializer hashSerializer;
GetNetBindComponent()->SerializeEntityCorrection(hashSerializer);
SerializeEntityCorrection(hashSerializer);
const AZ::HashValue32 localAuthorityHash = hashSerializer.GetHash();
@@ -233,7 +234,7 @@ namespace Multiplayer
// only deserialize if we have data (for client/server profile/debug mismatches)
if (correction.GetSize() > 0)
{
GetNetBindComponent()->SerializeEntityCorrection(serializer);
SerializeEntityCorrection(serializer);
}
correction.Resize(serializer.GetSize());
@@ -313,7 +314,7 @@ namespace Multiplayer
// Apply the correction
AzNetworking::TrackChangedSerializer<AzNetworking::NetworkOutputSerializer> serializer(correction.GetBuffer(), static_cast<uint32_t>(correction.GetSize()));
GetNetBindComponent()->SerializeEntityCorrection(serializer);
SerializeEntityCorrection(serializer);
GetNetBindComponent()->NotifyCorrection();
#ifndef AZ_RELEASE_BUILD
@@ -325,7 +326,7 @@ namespace Multiplayer
{
// Read out state values
AzNetworking::StringifySerializer serverValues;
GetNetBindComponent()->SerializeEntityCorrection(serverValues);
SerializeEntityCorrection(serverValues);
PrintCorrectionDifferences(*iter->second, serverValues);
}
else
@@ -452,7 +453,7 @@ namespace Multiplayer
// Generate a hash based on the current client predicted states
AzNetworking::HashSerializer hashSerializer;
GetNetBindComponent()->SerializeEntityCorrection(hashSerializer);
SerializeEntityCorrection(hashSerializer);
// Save this input and discard move history outside our client rewind window
m_inputHistory.PushBack(input);
@@ -480,7 +481,7 @@ namespace Multiplayer
{
m_predictiveStateHistory.erase(m_predictiveStateHistory.begin());
}
GetNetBindComponent()->SerializeEntityCorrection(*inputHistory);
SerializeEntityCorrection(*inputHistory);
m_predictiveStateHistory.emplace(m_clientInputId, AZStd::move(inputHistory));
}
#endif
@@ -493,6 +494,18 @@ namespace Multiplayer
}
}
bool LocalPredictionPlayerInputComponentController::SerializeEntityCorrection(AzNetworking::ISerializer& serializer)
{
bool result = GetNetBindComponent()->SerializeEntityCorrection(serializer);
NetworkHierarchyRootComponent* hierarchyComponent = GetParent().GetNetworkHierarchyRootComponent();
if (result && hierarchyComponent)
{
result = hierarchyComponent->SerializeEntityCorrection(serializer);
}
return result;
}
void LocalPredictionPlayerInputComponentController::UpdateBankedTime(AZ::TimeMs deltaTimeMs)
{
const double deltaTime = static_cast<double>(deltaTimeMs) / 1000.0;
@@ -452,4 +452,29 @@ namespace Multiplayer
}
}
bool NetworkHierarchyRootComponent::SerializeEntityCorrection(AzNetworking::ISerializer& serializer)
{
bool result = true;
INetworkEntityManager* networkEntityManager = AZ::Interface<INetworkEntityManager>::Get();
AZ_Assert(networkEntityManager, "NetworkEntityManager must be created.");
for (AZ::Entity* child : m_hierarchicalEntities)
{
if (child == GetEntity())
{
// Skip the root entity
continue;
}
NetEntityId childNetEntitydId = networkEntityManager->GetNetEntityIdById(child->GetId());
ConstNetworkEntityHandle childEntityHandle = networkEntityManager->GetEntity(childNetEntitydId);
NetBindComponent* netBindComponent = childEntityHandle.GetNetBindComponent();
AZ_Assert(netBindComponent, "No NetBindComponent, this should be impossible");
result = result && netBindComponent->SerializeEntityCorrection(serializer);
}
return result;
}
}
@@ -32,8 +32,8 @@ namespace Multiplayer
if (entity)
{
AZ_Assert(networkEntityTracker, "NetworkEntityTracker is not valid");
m_netBindComponent = networkEntityTracker->GetNetBindComponent(entity);
AZ_Assert(m_networkEntityTracker, "NetworkEntityTracker is not valid");
m_netBindComponent = m_networkEntityTracker->GetNetBindComponent(entity);
if (m_netBindComponent != nullptr)
{
m_netEntityId = m_netBindComponent->GetNetEntityId();