Rotate Rigidbody with AddTorque towards a specific location.

I have a main camera that rotates around an object (which I already move with AddForce).
Using AddTorque, I would like the object to rotate its Y axis of rotation in the direction in which the camera’s Y axis of rotation points so as to simulate the rotation of a person turning around.
To do this I thought of using a force that gave me 0 when the Y axes of the two objects are the same, but I tried and the rigidbody covers only one part of the rotation of the camera while the other part is as if it not is detected.

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

rotation my object desired rotation

What do you mean with “one part” of the rotation? If you mean only 1 dimension, that’s because in your code you only compare the y coordinate. You should do it for all rotations.

Take a look at this: AddTorque to rotate rigidbody to look at a point - Questions & Answers - Unity Discussions

I don’t mean just one dimension (the Y axes are used only as a unit of measure in the script). I mean that rotation only works when I rotate the camera in a certain range, if I rotate it more the object no longer rotates.
You can also see from the video that I posted in “rotation my object” as with this script objects do not follow the whole rotation of the camera.

I had already heard of the PID controller but I didn’t quite understand how to use it, if someone describes me how to apply it for the desired result it would help me a lot.

Here we go again :slight_smile:
In your video you can see that after a certain point, the character suddenly rotates the other way. I assume this is because the “y” rotation wraps. This means it only has values between 0 and 359.999 degrees… or -180 and 180 or something else. That’s one of the reasons that working with Euler angles is not a good idea in this case.

Stick with vector math:

Vector3 camForward = Camera.main.transform.forward;
Vector3 rbForward = rb.transform.forward;

Vector3 torque = Vector3.Cross(camForward, rbForward);
rb.AddTorque(torque);

Maybe you have to swap camForward and rbForward in the Cross() function if the rigidbody turns the wrong way.

If you wish to only rotate around the world y-Axis, you have to project the torque vector onto this axis Unity - Scripting API: Vector3.Project

Vector3 torqueY = Vector3.Project(torque, Vector3.up);

Be aware that this code will overshoot the desired orientation. You can add rotational damping, either in the rigidbodies settings or yourself in code like this

rb.AddTorque(-rb.angularVelocity);

Concerning PID:
We already implemented two of the letters with the code that I gave you:
Proportional: The difference between the state and the target of the controlled system, also called error, is added proportionally (P) to the input of the system.

Differential: The derivative of the error is also added to the input of the system (in our case just the angular velocity)

Integral: The error is summed up over time and also added to the systems input. (We didn’t do this and we also don’t need to in this case)

Feedback control is a vast topic (that I happened to have studied) that is somewhat intimidating but for cases like “follow control” really understandable once you get the hang of it.

5 Likes

Very thanks for the reply :slight_smile:
Vector3.cross has given me good results with the inverted parts. I honestly knew him but I thought that it gave a vector halfway between vectors A and B, and therefore using it the object would have stopped halfway, but it is not so and instead it works. The flaw is that if I use it as it is, the X and Z axes also rotate, so I have to freeze these.

Vector3.Project together with the damping, it work, but the damping does not do its duty and the object often stops further ahead