2
\$\begingroup\$

I'm a little new to this so any help will be appreciated.


Context: I'm creating a simulated VR billiard game and trying to get the physics as realistic as possible. I have a cue ball being hit with a cue across a surface with accurate friction values calculated from real world trials.


Problem: The cue ball slides for longer than what it would slide in the real world. Realistically, when the velocity reaches 5/7th (~71%) of its initial velocity the ball transitions from sliding to rolling. However, in Unity, the transition happens much later at around 20-10% of the initial velocity. (this is due to how Unity calculates physics of interaction as a point of contact rather than an area of contact)


Question: I want to hard code it so that when the cue ball loses 5/7th of its initial velocity (at 71%*initial velocity), the sliding velocity is set to 0 and the cue ball continues to roll from its angular velocity. Theoretically, is this possible? or will changing the velocity/speed to zero instantly stop the ball from moving in its place? And how do I go about doing this? Thanks in advance.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

This sounds like it should be possible, though I've never tried it. The following code should get you most of the way there. You could then determine through experimentation how to adjust the velocity and angular velocity to achieve the desired effect.

private Rigidbody body;

void Start() {
    body = GetComponent<Rigidbody>();
}

void OnCollisionEnter(Collision collision) {
    StartCoroutine(SlideThenRoll());
}

IEnumerator SlideThenRoll() {
    yield return null; //wait a frame to make sure our velocity updates
    float initialSpeed = body.velocity.magnitude;
    float targetSpeed = .71 * initialSpeed;
    yield return new WaitUntil(() => body.velocity.magnitude <= targetSpeed);

    //you'll need to fill in this part
    body.velocity = //??
    body.angularVelocity = //??
}
```
\$\endgroup\$
2
  • \$\begingroup\$ Hey, Thanks for the excellent response. I think you addressed it very well. How would this work in 3D? Isn't velocity in 3D, meaning it would have 3 vectors? I'd probably set body.velocity = 0 and body.angularVelocity = initialSpeed \$\endgroup\$ Aug 17, 2020 at 23:59
  • 1
    \$\begingroup\$ @NedSunshine Notice I call body.velocity.magnitude, which uses the Pythagorean theorem to calculate the length of a vector. When the vector is a velocity, the length of the vector is the speed in units per second. \$\endgroup\$
    – Kevin
    Aug 18, 2020 at 0:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .