On a Discord server, I was asked how to do a damped spring torque. As in, you have a world rotation you want your Rigidbody to turn towards. I had just used these old methods I had laying around earlier in the day, so I thought I’d share here as well.
body.ApplySpringForceToward(targetPosition, spring, damping,
ForceMode.Acceleration);
body.ApplySpringTorqueToward(targetRotation, spring, damping,
ForceMode.Acceleration);
If using ForceMode.Acceleration, a spring of 500 and a damping of 20 gives a slightly jiggly but responsive motion for bodies regardless of mass.
public static void ApplySpringForceToward(this Rigidbody body,
Vector3 targetPosition, float strength, float damping,
ForceMode mode=ForceMode.Force)
{
if (body.isKinematic)
return;
Vector3 difference = (body.position - targetPosition);
Vector3 direction = difference.normalized;
float force = strength * difference.magnitude;
body.AddForce(-force * direction - body.velocity * damping,
mode);
}
public static void ApplySpringTorqueToward(this Rigidbody body,
Quaternion targetRotation, float strength, float damping,
ForceMode mode=ForceMode.Force)
{
if (body.isKinematic)
return;
Quaternion difference = ShortestRotation(
targetRotation, body.rotation);
difference.ToAngleAxis(out float degrees, out Vector3 axis);
axis.Normalize();
float radians = degrees * Mathf.Deg2Rad;
body.AddTorque(
(axis * radians * strength) - (body.angularVelocity * damping),
mode);
}
public static Quaternion ShortestRotation(Quaternion a, Quaternion b)
{
if (Quaternion.Dot(a, b) < 0)
return a * Quaternion.Inverse(b.Flipped());
return a * Quaternion.Inverse(b);
}