fix: PredictedRigidbody now always teleports to corrections to avoid objects not being able to move to a corrected position if there's another object inbetween

This commit is contained in:
mischa 2024-03-23 23:52:23 +08:00 committed by MrGadget
parent fb1fc3a0ae
commit dc2f35a347

View File

@ -15,12 +15,6 @@
namespace Mirror namespace Mirror
{ {
public enum CorrectionMode
{
Set, // rigidbody.position/rotation = ...
Move, // rigidbody.MovePosition/Rotation
}
// [RequireComponent(typeof(Rigidbody))] <- RB is moved out at runtime, can't require it. // [RequireComponent(typeof(Rigidbody))] <- RB is moved out at runtime, can't require it.
public class PredictedRigidbody : NetworkBehaviour public class PredictedRigidbody : NetworkBehaviour
{ {
@ -71,9 +65,6 @@ public class PredictedRigidbody : NetworkBehaviour
public bool oneFrameAhead = true; public bool oneFrameAhead = true;
[Header("Smoothing")] [Header("Smoothing")]
[Tooltip("Configure how to apply the corrected state.")]
public CorrectionMode correctionMode = CorrectionMode.Move;
[Tooltip("Snap to the server state directly when velocity is < threshold. This is useful to reduce jitter/fighting effects before coming to rest.\nNote this applies position, rotation and velocity(!) so it's still smooth.")] [Tooltip("Snap to the server state directly when velocity is < threshold. This is useful to reduce jitter/fighting effects before coming to rest.\nNote this applies position, rotation and velocity(!) so it's still smooth.")]
public float snapThreshold = 2; // 0.5 has too much fighting-at-rest, 2 seems ideal. public float snapThreshold = 2; // 0.5 has too much fighting-at-rest, 2 seems ideal.
@ -643,18 +634,22 @@ void ApplyState(double timestamp, Vector3 position, Quaternion rotation, Vector3
// call it before applying pos/rot/vel in case we need to set kinematic etc. // call it before applying pos/rot/vel in case we need to set kinematic etc.
OnBeforeApplyState(); OnBeforeApplyState();
// Rigidbody .position teleports, while .MovePosition interpolates // Rigidbody .position teleports, while .MovePosition interpolates.
// TODO is this a good idea? what about next capture while it's interpolating? // we always want to teleport to corrections.
if (correctionMode == CorrectionMode.Move) // otherwise if there A is moving to the right and is blocked by B,
{ // it would never get there causing objects at rest to jiggle around.
predictedRigidbody.MovePosition(position); // if (correctionMode == CorrectionMode.Move)
predictedRigidbody.MoveRotation(rotation); // {
} // predictedRigidbody.MovePosition(position);
else if (correctionMode == CorrectionMode.Set) // predictedRigidbody.MoveRotation(rotation);
{ // }
predictedRigidbody.position = position; // else if (correctionMode == CorrectionMode.Set)
predictedRigidbody.rotation = rotation; // {
} // predictedRigidbody.position = position;
// predictedRigidbody.rotation = rotation;
// }
predictedRigidbody.position = position;
predictedRigidbody.rotation = rotation;
// there's only one way to set velocity. // there's only one way to set velocity.
// (projects may keep Rigidbodies as kinematic sometimes. in that case, setting velocity would log an error) // (projects may keep Rigidbodies as kinematic sometimes. in that case, setting velocity would log an error)