WhiteBallPredicted.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using UnityEngine;
  2. namespace Mirror.Examples.BilliardsPredicted
  3. {
  4. public class WhiteBallPredicted : NetworkBehaviour
  5. {
  6. public LineRenderer dragIndicator;
  7. public Rigidbody rigidBody;
  8. public float forceMultiplier = 2;
  9. public float maxForce = 40;
  10. // remember start position to reset to after entering a pocket
  11. Vector3 startPosition;
  12. // cast mouse position on screen to world position
  13. bool MouseToWorld(out Vector3 position)
  14. {
  15. Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  16. Plane plane = new Plane(Vector3.up, transform.position);
  17. if (plane.Raycast(ray, out float distance))
  18. {
  19. position = ray.GetPoint(distance);
  20. return true;
  21. }
  22. position = default;
  23. return false;
  24. }
  25. void Awake()
  26. {
  27. startPosition = transform.position;
  28. }
  29. [ClientCallback]
  30. void OnMouseDown()
  31. {
  32. // enable drag indicator
  33. dragIndicator.SetPosition(0, transform.position);
  34. dragIndicator.SetPosition(1, transform.position);
  35. dragIndicator.gameObject.SetActive(true);
  36. }
  37. [ClientCallback]
  38. void OnMouseDrag()
  39. {
  40. // cast mouse position to world
  41. if (!MouseToWorld(out Vector3 current)) return;
  42. // drag indicator
  43. dragIndicator.SetPosition(0, transform.position);
  44. dragIndicator.SetPosition(1, current);
  45. }
  46. [ClientCallback]
  47. void OnMouseUp()
  48. {
  49. // cast mouse position to world
  50. if (!MouseToWorld(out Vector3 current)) return;
  51. // calculate delta from ball to mouse
  52. // ball may have moved since we started dragging,
  53. // so always use current ball position here.
  54. Vector3 from = transform.position;
  55. // debug drawing: only works if Gizmos are enabled!
  56. Debug.DrawLine(from, current, Color.white, 2);
  57. // calculate pending force delta
  58. Vector3 delta = from - current;
  59. Vector3 force = delta * forceMultiplier;
  60. // there should be a maximum allowed force
  61. force = Vector3.ClampMagnitude(force, maxForce);
  62. // forward the event to the local player's object.
  63. // the ball isn't part of the local player.
  64. NetworkClient.localPlayer.GetComponent<PlayerPredicted>().OnDraggedBall(force);
  65. // disable drag indicator
  66. dragIndicator.gameObject.SetActive(false);
  67. }
  68. // reset position when entering a pocket.
  69. // there's only one trigger in the scene (the pocket).
  70. [ServerCallback]
  71. void OnTriggerEnter(Collider other)
  72. {
  73. rigidBody.position = startPosition;
  74. rigidBody.Sleep(); // reset forces
  75. // GetComponent<NetworkRigidbodyUnreliable>().RpcTeleport(startPosition);
  76. }
  77. [ClientCallback]
  78. void OnGUI()
  79. {
  80. // have a button to reply exactly the same force in every hit for easier testing.
  81. if (GUI.Button(new Rect(10, 150, 200, 20), "Hit!"))
  82. {
  83. // hit with a slight angle so the red balls spread out in all directions
  84. Vector3 force = Vector3.ClampMagnitude(new Vector3(10, 0, 600), maxForce);
  85. NetworkClient.localPlayer.GetComponent<PlayerPredicted>().OnDraggedBall(force);
  86. }
  87. }
  88. }
  89. }