PredictedRigidbodyVisual.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using System;
  2. using UnityEngine;
  3. namespace Mirror
  4. {
  5. [Obsolete("Prediction is under development, do not use this yet.")]
  6. public class PredictedRigidbodyVisual : MonoBehaviour
  7. {
  8. [Tooltip("The predicted rigidbody to follow.")]
  9. public PredictedRigidbody target;
  10. Rigidbody targetRigidbody;
  11. // settings are applied in the other PredictedRigidbody component and then copied here.
  12. [HideInInspector] public float positionInterpolationSpeed = 15; // 10 is a little too low for billiards at least
  13. [HideInInspector] public float rotationInterpolationSpeed = 10;
  14. [HideInInspector] public float teleportDistanceMultiplier = 10;
  15. // we add this component manually from PredictedRigidbody.
  16. // so assign this in Start. target isn't set in Awake yet.
  17. void Start()
  18. {
  19. targetRigidbody = target.GetComponent<Rigidbody>();
  20. }
  21. // always follow in late update, after update modified positions
  22. void LateUpdate()
  23. {
  24. // if target gets network destroyed for any reason, destroy visual
  25. if (targetRigidbody == null || target.gameObject == null)
  26. {
  27. Destroy(gameObject);
  28. return;
  29. }
  30. // hard follow:
  31. // transform.position = targetRigidbody.position;
  32. // transform.rotation = targetRigidbody.rotation;
  33. // if we are further than N colliders sizes behind, then teleport
  34. float colliderSize = target.GetComponent<Collider>().bounds.size.magnitude;
  35. float threshold = colliderSize * teleportDistanceMultiplier;
  36. float distance = Vector3.Distance(transform.position, targetRigidbody.position);
  37. if (distance > threshold)
  38. {
  39. transform.position = targetRigidbody.position;
  40. transform.rotation = targetRigidbody.rotation;
  41. Debug.Log($"[PredictedRigidbodyVisual] Teleported because distance {distance:F2} > threshold {threshold:F2}");
  42. return;
  43. }
  44. // smoothly interpolate to the target position.
  45. // speed relative to how far away we are
  46. float positionStep = distance * positionInterpolationSpeed;
  47. // speed relative to how far away we are.
  48. // => speed increases by distance² because the further away, the
  49. // sooner we need to catch the fuck up
  50. // float positionStep = (distance * distance) * interpolationSpeed;
  51. transform.position = Vector3.MoveTowards(transform.position, targetRigidbody.position, positionStep * Time.deltaTime);
  52. // smoothly interpolate to the target rotation.
  53. // Quaternion.RotateTowards doesn't seem to work at all, so let's use SLerp.
  54. transform.rotation = Quaternion.Slerp(transform.rotation, targetRigidbody.rotation, rotationInterpolationSpeed * Time.deltaTime);
  55. }
  56. }
  57. }