# Rotate Rigidbody to face away from camera with AddTorque

I have a camera that rotates around an object with "Look At" .

I want the object to rotate to face the direction the camera is pointing (Camera.main.transform.forward) using AddTorque, but I can't understand how.

I tried to create a rotation in which the more the object's forward vector rotates towards the camera, the more it should slow down the rotation until it stops. But it only works in sections, when I use the rotation of the camera the object rotates and then stops, as if it detects only one part of the rotation, while the other is a blind spot.

What equation can I use to rotate the object well?

var currentR = rb.rotation.y;
var targetR = Camera.main.transform.rotation.y;
rb.AddTorque(transform.up * 1000f * (targetR - currentR));


@DMGregory♦ I put your script as it is in a separate new script on a new object, equipped with a rigidbody. I post the script how I entered it. At "targetOrientation" I gave the value of "Quaternion.LookRotation (Camera.main.transform.forward);" because I want the object to follow the direction of that camera. The result is that all the axes of the rigidbody are influenced by the rotation (if I lift the camera the object turns towards the ground, etc.), and above all that the rotation works even if I block the axes with Freeze Rotation, and with this script the object is no longer affected by external forces.

public class rotation : MonoBehaviour
{
private Rigidbody rb;
public Transform direction;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
}

// Update is called once per frame
void Update()
{

Quaternion targetOrientation = Quaternion.LookRotation(Camera.main.transform.forward);
Quaternion rotationChange = targetOrientation * Quaternion.Inverse(rb.rotation);

rotationChange.ToAngleAxis(out float angle, out Vector3 axis);
if (angle > 180f)
angle -= 360f;

if (Mathf.Approximately(angle, 0)) {
rb.angularVelocity = Vector3.zero;
return;
}

var targetAngularVelocity = axis * angle / Time.deltaTime;

float catchUp = 1.0f;
targetAngularVelocity *= catchUp;

}
}


I set a command [if (Input.GetKeyDown (KeyCode.T)) rb.AddTorque (transform.up * 5500f, ForceMode.Impulse);] to rotate the object with an impulse and this does not work when your rotation script is active. I also place a video where you see the object before activating the rotation script, and after it is active, to see how it does not react to the impulse with T, and how it rotates reacting on all rotation axes, while I want only that the rigidbody only rotates its Y-axis of rotation, in the direction of the camera (as a person does when turning in one direction). In the video The axes of rotation X and Z are on freeze (otherwise without fixed the rotation the object falls moving). I also put a video of the desired effect taken from a game so as to explain me better.

• Note that transform.rotation is a Quaternion, so you should almost never try to access its x/y/z/w components one-by-one. The y component does not directly correspond to a yaw angle, which it looks like you're trying to use it as here. – DMGregory May 24 '20 at 15:58
• You completely skipped over the GetOrientationAwayFromCamera/TurretLookRotation portions of my answer that restrict the rotation to the vertical axis. If LookRotation was sufficient to get your desired behaviour, I would not have gone to the trouble of including those sections - so please implement the answer completely. – DMGregory May 25 '20 at 13:15

If you want to orient an object to face away from the camera, the first step is to compute the orientation you want it to have. You can use a "Turret Look Rotation" convenience method like this one to form an orientation perpendicular to a particular surface, while facing toward a particular direction.

// If your ground has hills/ramps, you might want to update this with your ground normal
// from your ground check raycast/shapecast.
Vector3 _groundNormal = new Vector3(0, 1, 0);

Quaternion GetOrientionAwayFromCamera() {
// To face in the direction of the camera axis, use this.
Vector3 approximateForward = Camera.main.transform.forward;

// To face away from the camera object, use this. It only makes a difference if your character
// can be off-center in the frame, facing leftward when they're on the left side of the screen.
// Vector3 approximateForward = transform.position - Camera.main.transform.position;

return TurretLookRotation(approximateForward, _groundNormal);
}


Now the easiest way to get a rigidbody to face that new orientation is with MoveRotation:

var targetOrientation = GetOrientationAwayFromCamera();
rigidbody.MoveRotation(targetOrientation);


But if you'd prefer to compute the torque to reach this orientation yourself, it's:

// Compute the change in orientation we need to impart.
Quaternion rotationChange = targetOrientation * Quaternion.Inverse(rigidbody.rotation);

// Convert to an angle-axis representation, with angle in range -180...180
rotationChange.ToAngleAxis(out float angle, out Vector3 axis);
if (angle > 180f)
angle -= 360f;

// If we're already facing the right way, just stop.
// This avoids problems with the infinite axes ToAngleAxis gives us in this case.
if (Mathf.Approximately(angle, 0)) {
rigidbody.angularVelocity = Vector3.zero;
return;
}

// If you need to, you can enforce a cap here on the maximum rotation you'll
// allow in a single step, to prevent overly jerky movement from upsetting your sim.
// angle = Mathf.Clamp(angle, -90f, 90f);

// Compute an angular velocity that will bring us to the target orientation
// in a single time step.
var targetAngularVelocity = axis * angle / Time.deltaTime;

// You can reduce this parameter to smooth the movement over multiple time steps,
// to help reduce the effect of sudden jerks.
float catchUp = 1.0f;
targetAngularVelocity *= catchUp;

// Apply a torque to finish the job.

• Ah. When your orientation is already facing the direction you want, AngleAxis gives back an infinite axis. Checking if the angle is zero and taking an early-out fixes this. I've edited the question to show that. – DMGregory May 24 '20 at 21:56