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;
}
angle *= Mathf.Deg2Rad;
var targetAngularVelocity = axis * angle / Time.deltaTime;
float catchUp = 1.0f;
targetAngularVelocity *= catchUp;
rb.AddTorque(targetAngularVelocity - rb.angularVelocity, ForceMode.VelocityChange);
}
}
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.
transform.rotation
is aQuaternion
, so you should almost never try to access itsx
/y
/z
/w
components one-by-one. They
component does not directly correspond to a yaw angle, which it looks like you're trying to use it as here. \$\endgroup\$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. \$\endgroup\$