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
\$\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 = //??
}
```
| improve this answer | |
\$\endgroup\$
  • \$\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\$ – NedSunshine Aug 17 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 at 0:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.