Predicted Billiards: fix dragging with predicted Rigidbody

This commit is contained in:
mischa 2024-03-20 21:19:02 +08:00
parent 376ed53483
commit a39c557e13

View File

@ -1,3 +1,4 @@
using System;
using UnityEngine; using UnityEngine;
namespace Mirror.Examples.BilliardsPredicted namespace Mirror.Examples.BilliardsPredicted
@ -5,6 +6,7 @@ namespace Mirror.Examples.BilliardsPredicted
public class WhiteBallPredicted : NetworkBehaviour public class WhiteBallPredicted : NetworkBehaviour
{ {
public LineRenderer dragIndicator; public LineRenderer dragIndicator;
public float dragTolerance = 1.0f;
public Rigidbody rigidBody; public Rigidbody rigidBody;
public float forceMultiplier = 2; public float forceMultiplier = 2;
public float maxForce = 40; public float maxForce = 40;
@ -12,6 +14,8 @@ public class WhiteBallPredicted : NetworkBehaviour
// remember start position to reset to after entering a pocket // remember start position to reset to after entering a pocket
Vector3 startPosition; Vector3 startPosition;
bool draggingStartedOverObject;
// cast mouse position on screen to world position // cast mouse position on screen to world position
bool MouseToWorld(out Vector3 position) bool MouseToWorld(out Vector3 position)
{ {
@ -31,6 +35,77 @@ void Awake()
startPosition = transform.position; startPosition = transform.position;
} }
[ClientCallback]
void Update()
{
// mouse down on the white ball?
if (Input.GetMouseButtonDown(0))
{
if (MouseToWorld(out Vector3 position))
{
// allow dragging if mouse is 'close enough'.
// balls are moving so we don't need to be exactly on it.
float distance = Vector3.Distance(position, transform.position);
if (distance <= dragTolerance)
{
// enable drag indicator
dragIndicator.SetPosition(0, transform.position);
dragIndicator.SetPosition(1, transform.position);
dragIndicator.gameObject.SetActive(true);
draggingStartedOverObject = true;
}
}
}
// mouse button dragging?
else if (Input.GetMouseButton(0))
{
// cast mouse position to world
if (draggingStartedOverObject && MouseToWorld(out Vector3 current))
{
// drag indicator
dragIndicator.SetPosition(0, transform.position);
dragIndicator.SetPosition(1, current);
}
}
// mouse button up?
else if (Input.GetMouseButtonUp(0))
{
// cast mouse position to world
if (draggingStartedOverObject && MouseToWorld(out Vector3 current))
{
// calculate delta from ball to mouse
// ball may have moved since we started dragging,
// so always use current ball position here.
Vector3 from = transform.position;
// debug drawing: only works if Gizmos are enabled!
Debug.DrawLine(from, current, Color.white, 2);
// calculate pending force delta
Vector3 delta = from - current;
Vector3 force = delta * forceMultiplier;
// there should be a maximum allowed force
force = Vector3.ClampMagnitude(force, maxForce);
// forward the event to the local player's object.
// the ball isn't part of the local player.
NetworkClient.localPlayer.GetComponent<PlayerPredicted>().OnDraggedBall(force);
// disable drag indicator
dragIndicator.gameObject.SetActive(false);
}
draggingStartedOverObject = false;
}
}
// OnMouse callbacks don't work for predicted objects because we need to
// move the collider out of the main object ocassionally.
// besides, having a drag tolerance and not having to click exactly on
// the white ball is nice.
/*
[ClientCallback] [ClientCallback]
void OnMouseDown() void OnMouseDown()
{ {
@ -79,6 +154,7 @@ void OnMouseUp()
// disable drag indicator // disable drag indicator
dragIndicator.gameObject.SetActive(false); dragIndicator.gameObject.SetActive(false);
} }
*/
// reset position when entering a pocket. // reset position when entering a pocket.
// there's only one trigger in the scene (the pocket). // there's only one trigger in the scene (the pocket).