Search Unity

Resolved Best Method To Make Rigidbody Spring To Upright Rotation?

Discussion in 'Physics' started by Connorses, Jun 16, 2021.

  1. Connorses

    Connorses

    Joined:
    Jan 28, 2016
    Posts:
    15
    I'm trying to make a rigidbody stand up in a way that feels springy. Basically, if it tips over, apply torque to push it upright again.

    So far I've tried putting a Configurable Joint on it, and setting "Angular Z Motion" and "Angular X Motion" to "Limited", and putting various values into the angular limit boxes such as Spring, or Bounciness. I've only ever gotten it to rigidly lock the X and Z rotation using this method.

    I've also tried writing a script to apply the necessary torque, but I lack the 3D math skills to know how to determine the angle to rotate on.
     
  2. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    For this, the cross product is used. Given two vectors, the cross product finds the vector that is perpendicular to both.
    So when you feed the up-direction of the rigid body and the world-up-direction into the cross product, you'll get the torque vector that you need to rotate the rigidbody into the given direction (up, in your case).

    Add the following code to you FixedUpdate:
    Code (CSharp):
    1.             float springStrength = 1;
    2.             float damperStrength = 1;
    3.  
    4.             var springTorque = springStrength * Vector3.Cross(rb.transform.up, Vector3.up);
    5.             var dampTorque = damperStrength * -rb.angularVelocity;
    6.             rb.AddTorque(springTorque + dampTorque, ForceMode.Acceleration);
    7.  
    I haven't tested this exact piece of code, but this is the concept I'm using. Could be that you have to swap the two arguments of Vector3.Cross in case you're moving in the wrong direction.

    springStrength and damperStrength need to be tweaked. SpringStrength means "how violently should we bring back the orientation to up, given a certain error". DamperStrength helps not to overshoot. Best make these properties public to tweak them at runtime.

    I hope this helps!
     
    OpticalOverride likes this.
  3. Connorses

    Connorses

    Joined:
    Jan 28, 2016
    Posts:
    15
    Thanks a ton! I will try out your code tomorrow... I found a simplified solution at this url which works fine, however it does not include damping like yours does.