perf(Prediction): optimize ghosts. deep profiling: 93 objects before=0.08ms after =0.03ms!

This commit is contained in:
mischa 2024-01-28 12:36:17 +01:00
parent 1899539e03
commit 2b92ac7674
3 changed files with 19 additions and 9 deletions

View File

@ -156,7 +156,7 @@ protected virtual void CreateGhosts()
// add the PredictedRigidbodyPhysical component
PredictedRigidbodyPhysicsGhost physicsGhostRigidbody = physicsCopy.AddComponent<PredictedRigidbodyPhysicsGhost>();
physicsGhostRigidbody.target = this;
physicsGhostRigidbody.target = tf;
physicsGhostRigidbody.ghostDistanceThreshold = ghostDistanceThreshold;
physicsGhostRigidbody.ghostEnabledCheckInterval = ghostEnabledCheckInterval;
@ -186,7 +186,7 @@ protected virtual void CreateGhosts()
remoteCopy.transform.rotation = tf.rotation; // world rotation!
remoteCopy.transform.localScale = tf.lossyScale; // world scale!
PredictedRigidbodyRemoteGhost predictedGhost = remoteCopy.AddComponent<PredictedRigidbodyRemoteGhost>();
predictedGhost.target = this;
predictedGhost.target = tf;
predictedGhost.ghostDistanceThreshold = ghostDistanceThreshold;
predictedGhost.ghostEnabledCheckInterval = ghostEnabledCheckInterval;
CopyRenderersAsGhost(remoteCopy, remoteGhostMaterial);

View File

@ -7,8 +7,10 @@ namespace Mirror
{
public class PredictedRigidbodyPhysicsGhost : MonoBehaviour
{
// this is performance critical, so store target's .Transform instead of
// PredictedRigidbody, this way we don't need to call the .transform getter.
[Tooltip("The predicted rigidbody owner.")]
public PredictedRigidbody target;
public Transform target;
// ghost (settings are copyed from PredictedRigidbody)
MeshRenderer ghost;
@ -16,13 +18,15 @@ public class PredictedRigidbodyPhysicsGhost : MonoBehaviour
public float ghostEnabledCheckInterval = 0.2f;
double lastGhostEnabledCheckTime = 0;
// cache
// cache components because this is performance critical!
Transform tf;
Collider co;
// we add this component manually from PredictedRigidbody.
// so assign this in Start. target isn't set in Awake yet.
void Start()
{
tf = transform;
co = GetComponent<Collider>();
ghost = GetComponent<MeshRenderer>();
}
@ -43,7 +47,7 @@ void UpdateGhostRenderers()
// otherwise it just looks like z-fighting the whole time.
// => iterated the renderers we found when creating the visual copy.
// we don't want to GetComponentsInChildren every time here!
bool insideTarget = Vector3.Distance(transform.position, target.transform.position) <= ghostDistanceThreshold;
bool insideTarget = Vector3.Distance(tf.position, target.position) <= ghostDistanceThreshold;
ghost.enabled = !insideTarget;
}
@ -53,7 +57,7 @@ void UpdateGhostRenderers()
void LateUpdate()
{
// if owner gets network destroyed for any reason, destroy visual
if (target == null || target.gameObject == null) Destroy(gameObject);
if (target == null) Destroy(gameObject);
}
// also show a yellow gizmo for the predicted & corrected physics.

View File

@ -5,8 +5,10 @@ namespace Mirror
{
public class PredictedRigidbodyRemoteGhost : MonoBehaviour
{
// this is performance critical, so store target's .Transform instead of
// PredictedRigidbody, this way we don't need to call the .transform getter.
[Tooltip("The predicted rigidbody owner.")]
public PredictedRigidbody target;
public Transform target;
// ghost (settings are copyed from PredictedRigidbody)
MeshRenderer ghost;
@ -14,10 +16,14 @@ public class PredictedRigidbodyRemoteGhost : MonoBehaviour
public float ghostEnabledCheckInterval = 0.2f;
double lastGhostEnabledCheckTime = 0;
// cache components because this is performance critical!
Transform tf;
// we add this component manually from PredictedRigidbody.
// so assign this in Start. target isn't set in Awake yet.
void Start()
{
tf = transform;
ghost = GetComponent<MeshRenderer>();
}
@ -37,7 +43,7 @@ void UpdateGhostRenderers()
// otherwise it just looks like z-fighting the whole time.
// => iterated the renderers we found when creating the visual copy.
// we don't want to GetComponentsInChildren every time here!
bool insideTarget = Vector3.Distance(transform.position, target.transform.position) <= ghostDistanceThreshold;
bool insideTarget = Vector3.Distance(tf.position, target.position) <= ghostDistanceThreshold;
ghost.enabled = !insideTarget;
}
@ -47,7 +53,7 @@ void UpdateGhostRenderers()
void LateUpdate()
{
// if owner gets network destroyed for any reason, destroy visual
if (target == null || target.gameObject == null) Destroy(gameObject);
if (target == null) Destroy(gameObject);
}
}
}