mirror of
https://github.com/GTA-ASM/SanAndreasUnity
synced 2024-11-25 05:20:17 +00:00
performance optimizations
This commit is contained in:
parent
d4871f254b
commit
9bf580291f
1 changed files with 52 additions and 40 deletions
|
@ -2,7 +2,6 @@ using UnityEngine;
|
||||||
using Mirror;
|
using Mirror;
|
||||||
using SanAndreasUnity.Utilities;
|
using SanAndreasUnity.Utilities;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace SanAndreasUnity.Net
|
namespace SanAndreasUnity.Net
|
||||||
{
|
{
|
||||||
|
@ -77,9 +76,6 @@ namespace SanAndreasUnity.Net
|
||||||
// timestamp of server when this data was sent (batch timestamp)
|
// timestamp of server when this data was sent (batch timestamp)
|
||||||
public double sentNetworkTime;
|
public double sentNetworkTime;
|
||||||
|
|
||||||
// network time when this data was received
|
|
||||||
public double receivedNetworkTime;
|
|
||||||
|
|
||||||
public void Apply(Transform tr)
|
public void Apply(Transform tr)
|
||||||
{
|
{
|
||||||
tr.localPosition = this.Position;
|
tr.localPosition = this.Position;
|
||||||
|
@ -92,10 +88,18 @@ namespace SanAndreasUnity.Net
|
||||||
|
|
||||||
private readonly NetworkBehaviour m_networkBehaviour;
|
private readonly NetworkBehaviour m_networkBehaviour;
|
||||||
|
|
||||||
private readonly Queue<GameObject> m_visualizationQueue = new Queue<GameObject>();
|
private Queue<GameObject> m_visualizationQueue = null; // null to save memory
|
||||||
|
|
||||||
private readonly Queue<SyncData> m_syncDataBuffer = new Queue<SyncData>();
|
// Buffer which holds received snapshots, ordered by remote timestamp. Queue seems to be better
|
||||||
public int SnapshotBufferCount => m_syncDataBuffer.Count;
|
// choice than List, because
|
||||||
|
// we often remove multiple elements from it, so the comparison boils down to: Dequeue() multiple
|
||||||
|
// times vs RemoveRange().
|
||||||
|
private Queue<SyncData> m_syncDataBuffer = null; // null to save memory server-side
|
||||||
|
|
||||||
|
public int SnapshotBufferCount => m_syncDataBuffer?.Count ?? 0;
|
||||||
|
|
||||||
|
// cached for fast access, otherwise we would have to iterate through Queue
|
||||||
|
private SyncData m_lastAddedSnapshot;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,7 +131,6 @@ namespace SanAndreasUnity.Net
|
||||||
var syncData = new SyncData();
|
var syncData = new SyncData();
|
||||||
|
|
||||||
syncData.sentNetworkTime = NetworkClient.connection.remoteTimeStamp;
|
syncData.sentNetworkTime = NetworkClient.connection.remoteTimeStamp;
|
||||||
syncData.receivedNetworkTime = NetworkTime.time;
|
|
||||||
|
|
||||||
syncData.Position = reader.ReadVector3();// + syncData.velocity * this.syncInterval;
|
syncData.Position = reader.ReadVector3();// + syncData.velocity * this.syncInterval;
|
||||||
syncData.Rotation = Quaternion.Euler(reader.ReadVector3());
|
syncData.Rotation = Quaternion.Euler(reader.ReadVector3());
|
||||||
|
@ -158,12 +161,18 @@ namespace SanAndreasUnity.Net
|
||||||
{
|
{
|
||||||
if (!m_parameters.visualize || m_parameters.maxNumVisualizations <= 0)
|
if (!m_parameters.visualize || m_parameters.maxNumVisualizations <= 0)
|
||||||
{
|
{
|
||||||
while (m_visualizationQueue.Count > 0)
|
if (m_visualizationQueue != null)
|
||||||
Object.Destroy(m_visualizationQueue.Dequeue());
|
{
|
||||||
|
while (m_visualizationQueue.Count > 0)
|
||||||
|
Object.Destroy(m_visualizationQueue.Dequeue());
|
||||||
|
m_visualizationQueue = null;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_visualizationQueue ??= new Queue<GameObject>();
|
||||||
|
|
||||||
while (m_visualizationQueue.Count >= m_parameters.maxNumVisualizations)
|
while (m_visualizationQueue.Count >= m_parameters.maxNumVisualizations)
|
||||||
Object.Destroy(m_visualizationQueue.Dequeue());
|
Object.Destroy(m_visualizationQueue.Dequeue());
|
||||||
|
|
||||||
|
@ -187,23 +196,27 @@ namespace SanAndreasUnity.Net
|
||||||
{
|
{
|
||||||
if (m_parameters.clientUpdateType != ClientUpdateType.SnapshotInterpolation)
|
if (m_parameters.clientUpdateType != ClientUpdateType.SnapshotInterpolation)
|
||||||
{
|
{
|
||||||
m_syncDataBuffer.Clear();
|
m_syncDataBuffer = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_syncDataBuffer ??= new Queue<SyncData>();
|
||||||
|
|
||||||
if (m_syncDataBuffer.Count == 0)
|
if (m_syncDataBuffer.Count == 0)
|
||||||
{
|
{
|
||||||
m_syncDataBuffer.Enqueue(syncData);
|
m_syncDataBuffer.Enqueue(syncData);
|
||||||
|
m_lastAddedSnapshot = syncData;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_syncDataBuffer.Last().sentNetworkTime >= syncData.sentNetworkTime)
|
if (m_lastAddedSnapshot.sentNetworkTime >= syncData.sentNetworkTime)
|
||||||
{
|
{
|
||||||
// can happen if packets arrive out of order (eg. on UDP transport)
|
// can happen if packets arrive out of order (eg. on UDP transport)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_syncDataBuffer.Enqueue(syncData);
|
m_syncDataBuffer.Enqueue(syncData);
|
||||||
|
m_lastAddedSnapshot = syncData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
|
@ -243,40 +256,39 @@ namespace SanAndreasUnity.Net
|
||||||
|
|
||||||
private void UpdateClientUsingSnapshotInterpolation()
|
private void UpdateClientUsingSnapshotInterpolation()
|
||||||
{
|
{
|
||||||
/*if (SnapshotInterpolation.Compute(
|
if (null == m_syncDataBuffer || m_syncDataBuffer.Count == 0)
|
||||||
NetworkTime.localTime,
|
|
||||||
Time.deltaTime,
|
|
||||||
ref m_clientInterpolationTime,
|
|
||||||
m_networkBehaviour.syncInterval * 2f,
|
|
||||||
m_syncDataBuffer,
|
|
||||||
4,
|
|
||||||
0.1f,
|
|
||||||
DoSnapshotInterpolation,
|
|
||||||
out SyncData computed))
|
|
||||||
{
|
|
||||||
this.SetPosition(computed.Position);
|
|
||||||
this.SetRotation(computed.Rotation);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (m_syncDataBuffer.Count == 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double currentNetworkTime = NetworkTime.time - m_parameters.snapshotLatency;
|
double currentNetworkTime = NetworkTime.time - m_parameters.snapshotLatency;
|
||||||
|
|
||||||
SyncData syncDataOfHigher;
|
// find higher and lower snapshots - those are snapshots that surround the 'currentNetworkTime'
|
||||||
SyncData syncDataOfLower;
|
|
||||||
|
|
||||||
int firstHigherIndex = m_syncDataBuffer.FindIndex(_ => _.sentNetworkTime >= currentNetworkTime);
|
SyncData syncDataOfHigher = default;
|
||||||
if (firstHigherIndex >= 0)
|
SyncData syncDataOfLower = default;
|
||||||
|
|
||||||
|
// note: using foreach with Queue<T> will not allocate memory
|
||||||
|
bool isFirst = true;
|
||||||
|
bool foundFirstHigher = false;
|
||||||
|
foreach (SyncData snapshot in m_syncDataBuffer)
|
||||||
{
|
{
|
||||||
syncDataOfHigher = m_syncDataBuffer.ElementAt(firstHigherIndex);
|
if (snapshot.sentNetworkTime >= currentNetworkTime)
|
||||||
syncDataOfLower = firstHigherIndex > 0 ? m_syncDataBuffer.ElementAt(firstHigherIndex - 1) : syncDataOfHigher;
|
{
|
||||||
|
syncDataOfHigher = snapshot;
|
||||||
|
if (isFirst)
|
||||||
|
syncDataOfLower = snapshot;
|
||||||
|
foundFirstHigher = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
isFirst = false;
|
||||||
|
syncDataOfLower = snapshot;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!foundFirstHigher)
|
||||||
{
|
{
|
||||||
// we are ahead of all snapshots
|
// we are ahead of all snapshots
|
||||||
syncDataOfHigher = m_syncDataBuffer.Last();
|
// use the last snapshot for both higher and lower snapshot
|
||||||
syncDataOfLower = syncDataOfHigher;
|
syncDataOfHigher = syncDataOfLower;
|
||||||
}
|
}
|
||||||
|
|
||||||
// interpolate between lower and higher syncdata
|
// interpolate between lower and higher syncdata
|
||||||
|
@ -378,7 +390,7 @@ namespace SanAndreasUnity.Net
|
||||||
m_currentSyncData.CalculatedVelocityMagnitude = float.PositiveInfinity;
|
m_currentSyncData.CalculatedVelocityMagnitude = float.PositiveInfinity;
|
||||||
m_currentSyncData.CalculatedAngularVelocityMagnitude = float.PositiveInfinity;
|
m_currentSyncData.CalculatedAngularVelocityMagnitude = float.PositiveInfinity;
|
||||||
m_nextSyncData = null;
|
m_nextSyncData = null;
|
||||||
m_syncDataBuffer.Clear();
|
m_syncDataBuffer?.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WarpToLatestSyncData()
|
public void WarpToLatestSyncData()
|
||||||
|
@ -393,7 +405,7 @@ namespace SanAndreasUnity.Net
|
||||||
|
|
||||||
m_currentSyncData = syncData;
|
m_currentSyncData = syncData;
|
||||||
m_nextSyncData = null;
|
m_nextSyncData = null;
|
||||||
m_syncDataBuffer.Clear();
|
m_syncDataBuffer?.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SyncData GetLatestSyncData()
|
public SyncData GetLatestSyncData()
|
||||||
|
|
Loading…
Reference in a new issue