Search Unity

Question Rotate Rigidbody with AddTorque towards a specific location.

Discussion in 'Physics' started by pappalardodd, May 25, 2020.

  1. pappalardodd

    pappalardodd

    Joined:
    Apr 13, 2020
    Posts:
    96
    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.

    Code (CSharp):
    1. var currentR = rb.rotation.y;
    2. var targetR = Camera.main.transform.rotation.y;
    3. rb.AddTorque(transform.up * 1000f * (targetR - currentR));
    rotation my object desired rotation
     
  2. Linkerbrain

    Linkerbrain

    Joined:
    Mar 27, 2020
    Posts:
    2
  3. pappalardodd

    pappalardodd

    Joined:
    Apr 13, 2020
    Posts:
    96
    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.
     
  4. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    Here we go again :)
    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:
    Code (CSharp):
    1. Vector3 camForward = Camera.main.transform.forward;
    2. Vector3 rbForward = rb.transform.forward;
    3.  
    4. Vector3 torque = Vector3.Cross(camForward, rbForward);
    5. rb.AddTorque(torque);
    6.  
    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 https://docs.unity3d.com/ScriptReference/Vector3.Project.html

    Code (CSharp):
    1. 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

    Code (CSharp):
    1. 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.
     
    Last edited: May 27, 2020
  5. pappalardodd

    pappalardodd

    Joined:
    Apr 13, 2020
    Posts:
    96
    Very thanks for the reply :)
    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
     
    Last edited: May 31, 2020