From 90d633fb2d735bc49bc09e1342d179f125ad94da Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 24 May 2023 22:59:22 +0200 Subject: [PATCH] Minor improvements to new replication hierarchy --- .../Networking/NetworkReplicationHierarchy.cpp | 18 ++++++++++++------ .../Networking/NetworkReplicationHierarchy.h | 6 ++++-- Source/Engine/Networking/NetworkReplicator.cpp | 3 ++- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp index 450f22d47..d86acfc7f 100644 --- a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp +++ b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp @@ -49,10 +49,11 @@ bool NetworkReplicationHierarchyUpdateResult::GetClientLocation(int32 clientInde void NetworkReplicationNode::AddObject(NetworkReplicationHierarchyObject obj) { - ASSERT(obj.Object && obj.ReplicationFPS > 0.0f); - - // Randomize initial replication update to spread rep rates more evenly for large scenes that register all objects within the same frame - obj.ReplicationUpdatesLeft = NetworkReplicationNodeObjectCounter++ % Math::Clamp(Math::RoundToInt(NetworkManager::NetworkFPS / obj.ReplicationFPS), 1, 60); + if (obj.ReplicationFPS > 0.0f) + { + // Randomize initial replication update to spread rep rates more evenly for large scenes that register all objects within the same frame + obj.ReplicationUpdatesLeft = NetworkReplicationNodeObjectCounter++ % Math::Clamp(Math::RoundToInt(NetworkManager::NetworkFPS / obj.ReplicationFPS), 1, 60); + } Objects.Add(obj); } @@ -79,7 +80,12 @@ void NetworkReplicationNode::Update(NetworkReplicationHierarchyUpdateResult* res const float networkFPS = NetworkManager::NetworkFPS / result->ReplicationScale; for (NetworkReplicationHierarchyObject& obj : Objects) { - if (obj.ReplicationUpdatesLeft > 0) + if (obj.ReplicationFPS <= 0.0f) + { + // Always relevant + result->AddObject(obj.Object); + } + else if (obj.ReplicationUpdatesLeft > 0) { // Move to the next frame obj.ReplicationUpdatesLeft--; @@ -87,7 +93,7 @@ void NetworkReplicationNode::Update(NetworkReplicationHierarchyUpdateResult* res else { NetworkClientsMask targetClients = result->GetClientsMask(); - if (result->_clientsHaveLocation) + if (result->_clientsHaveLocation && obj.CullDistance > 0.0f) { // Cull object against viewers locations if (const Actor* actor = obj.GetActor()) diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.h b/Source/Engine/Networking/NetworkReplicationHierarchy.h index 99770c5a4..55cd6b7b1 100644 --- a/Source/Engine/Networking/NetworkReplicationHierarchy.h +++ b/Source/Engine/Networking/NetworkReplicationHierarchy.h @@ -17,11 +17,12 @@ class Actor; API_STRUCT(NoDefault, Namespace = "FlaxEngine.Networking") struct FLAXENGINE_API NetworkReplicationHierarchyObject { DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkReplicationObjectInfo); + // The object to replicate. API_FIELD() ScriptingObjectReference Object; - // The target amount of the replication updates per second (frequency of the replication). Constrained by NetworkManager::NetworkFPS. + // The target amount of the replication updates per second (frequency of the replication). Constrained by NetworkManager::NetworkFPS. Use 0 for 'always relevant' object. API_FIELD() float ReplicationFPS = 60; - // The minimum distance from the player to the object at which it can process replication. For example, players further away won't receive object data. + // The minimum distance from the player to the object at which it can process replication. For example, players further away won't receive object data. Use 0 if unused. API_FIELD() float CullDistance = 15000; // Runtime value for update frames left for the next replication of this object. Matches NetworkManager::NetworkFPS calculated from ReplicationFPS. API_FIELD(Attributes="HideInEditor") uint16 ReplicationUpdatesLeft = 0; @@ -61,6 +62,7 @@ inline uint32 GetHash(const NetworkReplicationHierarchyObject& key) API_STRUCT(NoDefault, Namespace = "FlaxEngine.Networking") struct FLAXENGINE_API NetworkClientsMask { DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkClientsMask); + // The first 64 bits (each for one client). API_FIELD() uint64 Word0 = 0; // The second 64 bits (each for one client). diff --git a/Source/Engine/Networking/NetworkReplicator.cpp b/Source/Engine/Networking/NetworkReplicator.cpp index 6579d2cc9..8d0ba3c0e 100644 --- a/Source/Engine/Networking/NetworkReplicator.cpp +++ b/Source/Engine/Networking/NetworkReplicator.cpp @@ -1430,7 +1430,8 @@ void NetworkInternal::NetworkReplicatorUpdate() { ScriptingObject* obj = e.Object; auto it = Objects.Find(obj->GetID()); - ASSERT(it.IsNotEnd()); + if (it.IsEnd()) + continue; auto& item = it->Item; // Skip serialization of objects that none will receive