Search Unity

Rotate a transform to 45 degrees less than target transform

Discussion in 'Scripting' started by poolts, Jun 19, 2019.

  1. poolts

    poolts

    Joined:
    Aug 9, 2012
    Posts:
    113
    Hi all,

    I'm trying essentially do the following:
    1. Check if the rotation between my transform and my target rotations is more or less than 45 degrees
    2. If it's more than 45 degrees I want to set the transforms Y rotation to be the target's Y rotation minus 45 degrees
    3. If it's less than -45 degrees I want to set the transforms Y rotation to be the target's Y rotation add 45 degrees
    I have the follow code using Quaternions as I calculated it firstly using Euler, but it suffered from the 0 to 360 degree conversion (when my target rotated anti-clockwise past 0 degrees it would report it's Y rotation as 360 and broke the code, as it would enter my first condition even though it was moving anticlockwise, which it shouldn't).

    Code (CSharp):
    1. float rotationYDelta = m_vrCamTrans.localRotation.y - transform.localRotation.y;
    2.  
    3. if(rotationYDelta > Quaternion.Euler(0f, 45f, 0f).y)
    4. {
    5.     print("More than 45 diff");
    6.     transform.localRotation =
    7.         new Quaternion(
    8.             transform.localRotation.x,
    9.             m_vrCamTrans.localRotation.y - Quaternion.Euler(0f, 45f, 0f).y,
    10.             transform.localRotation.z,
    11.             transform.localRotation.w
    12.         );
    13. }
    14. else if (rotationYDelta < Quaternion.Euler(0f, -45f, 0f).y)
    15. {
    16.     print("Less than 45 diff");
    17.     transform.localRotation =
    18.         new Quaternion(
    19.             transform.localRotation.x,
    20.             m_vrCamTrans.localRotation.y - Quaternion.Euler(0f, -45f, 0f).y,
    21.             transform.localRotation.z,
    22.             transform.localRotation.w
    23.         );
    24. }
     
  2. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    The short version is that Quaternions don't work the way you expect them to. The y coordinate of a Quaternion is not the rotation around the y-axis, so your modifications aren't going to work. You probably want to use the Quaternion methods https://docs.unity3d.com/ScriptReference/Quaternion.html
    Make sure you don't miss where you are calculating rotationYDelta, as that also doesn't work.
    To add rotations together, you multiply the quaternions. To subtract, you multiply by the inverse.
    Code (csharp):
    1. Vector3 camForward = Vector3.ProjectOnPlane(m_vrCamTrans.forward, transform.up); // we want to make sure that the shortest angular distance between our two vectors is around our transform's y-axis, so we project the cam's forward vector into our local xz-plane
    2. float rotationDelta = Vector3.Angle(transform.forward, camForward); // the positive angle between our forward vector and the cam's, which should be an angle around our y-axis
    3. if(rotationDelta > 45.0f)
    4. {
    5.      float angle;
    6.      Vector3 axis;
    7.      Quaternion.FromToRotation(transform.forward, camForward).ToAngleAxis(out angle, out axis); // get the rotation from our forward vector to the cam's forward vector and convert it into a rotation around an axis (our local y axis) by an angle
    8.      // You could debug here to see if the axis is right
    9.      angle -= 45.0f; // instead of rotating all the way from our forward vector to the cam's, we rotate in that direction by 45 degrees less than it would take to point in the same direction.
    10.      transform.rotation *= Quaternion.AngleAxis(angle, axis); // actually do the rotation, by adding our current rotation and the rotation to get to our target.
    11. }
    Disclaimer: code not tested, probably needs adjusted, should get you going in the right direction though.