Skip to content

Commit 158c597

Browse files
author
mischa
committed
perf(PredictedRigidbody): next round of optimizations
1 parent c5aa7d5 commit 158c597

4 files changed

Lines changed: 42 additions & 30 deletions

File tree

Assets/Mirror/Components/PredictedRigidbody/PredictedRigidbody.cs

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,9 @@ protected virtual void SmoothFollowPhysicsCopy()
251251
*/
252252

253253
// FAST VERSION: this shows in profiler a lot, so cache EVERYTHING!
254-
Vector3 currentPosition = tf.position;
255-
Quaternion currentRotation = tf.rotation;
256-
Vector3 physicsPosition = physicsCopyTransform.position; // faster than accessing physicsCopyRigidbody!
257-
Quaternion physicsRotation = physicsCopyTransform.rotation; // faster than accessing physicsCopyRigidbody!
258-
float deltaTime = Time.deltaTime;
254+
tf.GetPositionAndRotation(out Vector3 currentPosition, out Quaternion currentRotation); // faster than tf.position + tf.rotation
255+
physicsCopyTransform.GetPositionAndRotation(out Vector3 physicsPosition, out Quaternion physicsRotation); // faster than physicsCopyRigidbody.position + physicsCopyRigidbody.rotation
256+
float deltaTime = Time.deltaTime;
259257

260258
float distance = Vector3.Distance(currentPosition, physicsPosition);
261259
if (distance > smoothFollowThreshold)
@@ -356,27 +354,35 @@ void RecordState()
356354
if (stateHistory.Count >= stateHistoryLimit)
357355
stateHistory.RemoveAt(0);
358356

357+
// grab current position/rotation/velocity only once.
358+
// this is performance critical, avoid calling .transform multiple times.
359+
tf.GetPositionAndRotation(out Vector3 currentPosition, out Quaternion currentRotation); // faster than accessing .position + .rotation manually
360+
Vector3 currentVelocity = physicsCopyRigidbody.velocity;
361+
359362
// calculate delta to previous state (if any)
360363
Vector3 positionDelta = Vector3.zero;
361364
Vector3 velocityDelta = Vector3.zero;
362-
Quaternion rotationDelta = Quaternion.identity;
365+
// Quaternion rotationDelta = Quaternion.identity; // currently unused
363366
if (stateHistory.Count > 0)
364367
{
365368
RigidbodyState last = stateHistory.Values[stateHistory.Count - 1];
366-
positionDelta = physicsCopyRigidbody.position - last.position;
367-
velocityDelta = physicsCopyRigidbody.velocity - last.velocity;
368-
rotationDelta = physicsCopyRigidbody.rotation * Quaternion.Inverse(last.rotation); // this is how you calculate a quaternion delta
369+
positionDelta = currentPosition - last.position;
370+
velocityDelta = currentVelocity - last.velocity;
371+
// rotationDelta = currentRotation * Quaternion.Inverse(last.rotation); // this is how you calculate a quaternion delta (currently unused, don't do the computation)
369372

370373
// debug draw the recorded state
371-
Debug.DrawLine(last.position, physicsCopyRigidbody.position, Color.red, lineTime);
374+
// Debug.DrawLine(last.position, currentPosition, Color.red, lineTime);
372375
}
373376

374377
// create state to insert
375378
RigidbodyState state = new RigidbodyState(
376379
predictedTime,
377-
positionDelta, physicsCopyRigidbody.position,
378-
rotationDelta, physicsCopyRigidbody.rotation,
379-
velocityDelta, physicsCopyRigidbody.velocity
380+
positionDelta,
381+
currentPosition,
382+
// rotationDelta, // currently unused
383+
currentRotation,
384+
velocityDelta,
385+
currentVelocity
380386
);
381387

382388
// add state to history
@@ -412,9 +418,12 @@ void ApplyState(double timestamp, Vector3 position, Quaternion rotation, Vector3
412418
stateHistory.Clear();
413419
stateHistory.Add(timestamp, new RigidbodyState(
414420
timestamp,
415-
Vector3.zero, position,
416-
Quaternion.identity, rotation,
417-
Vector3.zero, velocity
421+
Vector3.zero,
422+
position,
423+
// Quaternion.identity, // rotationDelta: currently unused
424+
rotation,
425+
Vector3.zero,
426+
velocity
418427
));
419428

420429
// user callback
@@ -446,9 +455,9 @@ void OnReceivedState(double timestamp, RigidbodyState state)
446455
// always update remote state ghost
447456
if (remoteCopy != null)
448457
{
449-
remoteCopy.transform.position = state.position;
450-
remoteCopy.transform.rotation = state.rotation;
451-
remoteCopy.transform.localScale = tf.lossyScale; // world scale! see CreateGhosts comment.
458+
Transform remoteCopyTransform = remoteCopy.transform;
459+
remoteCopyTransform.SetPositionAndRotation(state.position, state.rotation); // faster than .position + .rotation setters
460+
remoteCopyTransform.localScale = tf.lossyScale; // world scale! see CreateGhosts comment.
452461
}
453462

454463
// OPTIONAL performance optimization when comparing idle objects.
@@ -552,7 +561,7 @@ void OnReceivedState(double timestamp, RigidbodyState state)
552561

553562
// show the received correction position + velocity for debugging.
554563
// helps to compare with the interpolated/applied correction locally.
555-
Debug.DrawLine(state.position, state.position + state.velocity * 0.1f, Color.white, lineTime);
564+
//Debug.DrawLine(state.position, state.position + state.velocity * 0.1f, Color.white, lineTime);
556565

557566
// insert the correction and correct the history on top of it.
558567
// returns the final recomputed state after rewinding.
@@ -563,7 +572,7 @@ void OnReceivedState(double timestamp, RigidbodyState state)
563572
// for example, on same machine with near zero latency.
564573
// int correctedAmount = stateHistory.Count - afterIndex;
565574
// Debug.Log($"Correcting {name}: {correctedAmount} / {stateHistory.Count} states to final position from: {rb.position} to: {last.position}");
566-
Debug.DrawLine(physicsCopyRigidbody.position, recomputed.position, Color.green, lineTime);
575+
//Debug.DrawLine(physicsCopyRigidbody.position, recomputed.position, Color.green, lineTime);
567576
ApplyState(recomputed.timestamp, recomputed.position, recomputed.rotation, recomputed.velocity);
568577

569578
// user callback
@@ -620,7 +629,7 @@ public override void OnDeserialize(NetworkReader reader, bool initialState)
620629
Vector3 velocity = reader.ReadVector3();
621630

622631
// process received state
623-
OnReceivedState(timestamp, new RigidbodyState(timestamp, Vector3.zero, position, Quaternion.identity, rotation, Vector3.zero, velocity));
632+
OnReceivedState(timestamp, new RigidbodyState(timestamp, Vector3.zero, position, /*Quaternion.identity,*/ rotation, Vector3.zero, velocity));
624633
}
625634

626635
protected override void OnValidate()

Assets/Mirror/Components/PredictedRigidbody/RigidbodyState.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,25 @@ public struct RigidbodyState : PredictedState
1212
public Vector3 positionDelta { get; set; } // delta to get from last to this position
1313
public Vector3 position { get; set; }
1414

15-
public Quaternion rotationDelta { get; set; } // delta to get from last to this rotation
15+
// public Quaternion rotationDelta { get; set; } // delta to get from last to this rotation
1616
public Quaternion rotation { get; set; }
1717

1818
public Vector3 velocityDelta { get; set; } // delta to get from last to this velocity
1919
public Vector3 velocity { get; set; }
2020

2121
public RigidbodyState(
2222
double timestamp,
23-
Vector3 positionDelta, Vector3 position,
24-
Quaternion rotationDelta, Quaternion rotation,
25-
Vector3 velocityDelta, Vector3 velocity)
23+
Vector3 positionDelta,
24+
Vector3 position,
25+
// Quaternion rotationDelta, // currently unused
26+
Quaternion rotation,
27+
Vector3 velocityDelta,
28+
Vector3 velocity)
2629
{
2730
this.timestamp = timestamp;
2831
this.positionDelta = positionDelta;
2932
this.position = position;
30-
this.rotationDelta = rotationDelta;
33+
// this.rotationDelta = rotationDelta;
3134
this.rotation = rotation;
3235
this.velocityDelta = velocityDelta;
3336
this.velocity = velocity;

Assets/Mirror/Core/Prediction/Prediction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public interface PredictedState
1515
Vector3 positionDelta { get; set; }
1616

1717
Quaternion rotation { get; set; }
18-
Quaternion rotationDelta { get; set; }
18+
// Quaternion rotationDelta { get; set; } // currently unused
1919

2020
Vector3 velocity { get; set; }
2121
Vector3 velocityDelta { get; set; }

Assets/Mirror/Tests/Editor/Prediction/PredictionTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ struct TestState : PredictedState
1414
public Vector3 positionDelta { get; set; }
1515

1616
public Quaternion rotation { get; set; }
17-
public Quaternion rotationDelta { get; set; }
17+
// public Quaternion rotationDelta { get; set; } // currently unused
1818

1919
public Vector3 velocity { get; set; }
2020
public Vector3 velocityDelta { get; set; }
@@ -25,7 +25,7 @@ public TestState(double timestamp, Vector3 position, Vector3 positionDelta, Vect
2525
this.position = position;
2626
this.positionDelta = positionDelta;
2727
this.rotation = Quaternion.identity;
28-
this.rotationDelta = Quaternion.identity;
28+
// this.rotationDelta = Quaternion.identity;
2929
this.velocity = velocity;
3030
this.velocityDelta = velocityDelta;
3131
}

0 commit comments

Comments
 (0)