0
\$\begingroup\$

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


Context: I'm creating a VR billiard/pool 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 angular acceleration of the balls isn't realistic at all. Therefore the angular velocity is off (this is due to how Unity calculates physics of interaction as a point of contact rather than an area of contact and therefore friction calculation is done at one point causing it to rotate slower).


Question: How can I manually set the angular acceleration to a value in code until the angular acceleration is greater than or equals to horizontal velocity, then the angular acceleration is set to 0? Thanks in advance.

\$\endgroup\$
1
2
\$\begingroup\$

Unity doesn't have an 'angular acceleration' field that you can set. You can set the angular velocity in code, as I showed in your previous question about this. If you need to accelerate or decelerate the angular velocity, you can do this manually in your code.

void Update() {
    if (rigidbody.angularVelocity.magnitude < desiredAngularVelocity) {
        //scales the acceleration each frame
        rigidbody.angularVelocity = rigidbody.angularVelocity * accelerationRate * Time.deltaTime;
    }
}

or if you want the angular velocity to change by a constant rate rather than scaling it, I think this will work (haven't tested it):

void Update() {
    if (rigidbody.angularVelocity.magnitude < desiredAngularVelocity) {
        float angularSpeed = rigidBody.angularVelocity.magnitude;
        angularSpeed += acceleration * Time.deltaTime;
        rigidbody.angularVelocity = rigidbody.angularVelocity.normalized * angularSpeed;
    }
}

Or if you want to use forces, try rigidbody.AddTorque()

rigidbody.AddTorque(transform.right * 10000);

This is more complicated because torque is 3D; you'll have to calculate the correct direction for the torque.

You may wish to review all of the functions available to Rigidbodies.

\$\endgroup\$
6
  • \$\begingroup\$ Isn't Time.deltaTime simple the time between frames? Did you mean to have a timer in place indicating the time passed? \$\endgroup\$ Aug 19 '20 at 18:48
  • 2
    \$\begingroup\$ @NedSunshine Yes, Time.deltaTime is the amount of time that elapsed over the last frame. In my simple example, multiplying the acceleration rate by Time.deltaTime ensures that the acceleration is smooth even if the application framerate is inconsistent. \$\endgroup\$
    – Kevin
    Aug 19 '20 at 18:54
  • \$\begingroup\$ I'm not sure if I'm missing something. This and what I tried before don't accelerate the rotation. Wouldn't I expect this to cause the ball to rotate/roll faster over time? (ignoring the if statement) \$\endgroup\$ Aug 19 '20 at 19:11
  • 1
    \$\begingroup\$ Yes. Try adding Debug.Log("before: " + rigidbody.angularVelocity) before you change the velocity and Debug.Log("after: " + rigidbody.angularVelocity) after you change it; this may help you understand what's going on. \$\endgroup\$
    – Kevin
    Aug 19 '20 at 19:54
  • 1
    \$\begingroup\$ I found the root of the problem. It's the default limit of 7 to the angular velocity. docs.unity3d.com/ScriptReference/… \$\endgroup\$ Aug 19 '20 at 20:32

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.