Turn Direction To Match Rotation

I am looking to find out if I need to turn left (0,-1,0) or right (0,1,0) to match the rotation of another transform. (By the shortest rotation direction).

My current code is this, however, it does not seem to be working correctly.

        Vector3 cross = Vector3.Cross(transform.rotation * Vector3.forward, matchRotation.rotation * Vector3.forward);
float  rotationDirection = cross.y;

        if (rotationDirection == 0)
        {
            Debug.Log("Straight");
            rotation = 0;
        }

        else if (rotationDirection > 0)
        {
            Debug.Log("turn right");
            rotation = 1;
        }

        else if (rotationDirection < 0)
        {
            Debug.Log("turn left");
            rotation = -1;
        }

Unity has a built in function for signed angles so when i had a similar problem i used the following: float signedAngle = -Vector3.SignedAngle((targetCoord - transform.position), transform.forward, transform.up);

I believe with the negation it should fit your definition of left and right (if not delete the minus). I would suggest not using 0 tho, as i highly doubt you will always reach a perfect position without stuttering (left right left right…) if what you do is move in the Update loop based on deltaTime. Instead of 0 you may want to use a small targetPrecision float value. Depends on what you are doing with that code tho, hope this helps.

1 Like

@Yoreki , thanks for the post. I think its suffers the same issue as mine does, however. And otherwise is pretty much the same. Is that it relies on pos to calculate the angles. So the if the target rotation transform is behind or in front of the ‘player’ transform, then it would rotate different. Rather than just try and match the same rotation of the transform.

Oh, i’m sorry. I misread what you are trying to achieve. The line i posted you gives you a signed angle with which you can determine in which direction you’d have to turn so that you look at some other object. What you wanted however, was looking into the same direction as some other object, right?

It’s very simple to fix tho - since we are just calculating the wrong angle right now. Instead of calculating the angle towards the other object, which is (targetCoord-transform.position), we need to calculate the angle towards the looking direction of the other object, which is other.transform.forward. Using your code as a baseline, this script turns the object it is attached to towards the direction the other object is looking at:

public class SameLookDirectionAs : MonoBehaviour
{
    public GameObject other;

    // Start is called before the first frame update
    void Start()
    {
     
    }

    // Update is called once per frame
    void Update()
    {
        // Looking at an object:
        //float rotationDirection = -Vector3.SignedAngle((other.transform.position - transform.position), transform.forward, transform.up);

        // Looking in the same direction as an other object:
        float rotationDirection = -Vector3.SignedAngle((other.transform.forward), transform.forward, transform.up);

        if (rotationDirection == 0)
        {
            Debug.Log("straight");
            // No rotation needed here
        }

        else if (rotationDirection > 0)
        {
            Debug.Log("turn right");
            gameObject.transform.Rotate(new Vector3(0, 10 * Time.deltaTime, 0), Space.Self);
        }

        else if (rotationDirection < 0)
        {
            Debug.Log("turn left");
            gameObject.transform.Rotate(new Vector3(0, -10 * Time.deltaTime, 0), Space.Self);
        }
    }

Also, using 0 actually seems to work decently, at least with a rotation speed of 10 as in my example. For higher values, like 100 for example, you can run into the problem i described above, where the rotation overshoots the target rotation and thus needs to turn left, right, left, right, … until it randomly hits straight after a while. For that reason i’d still suggest using a small targetPrecision value instead of 0, if that’s at all what you are trying to do.

Hope this helps now.

1 Like

@Yoreki oreki, thanks. That looks really good. Ill give it a go! I am using it to set a character controller to match the rotation of the waypoint, once it reaches it. This way, my invisible waypoints (transform) can be both the pos to stop, and the rotation to look after arrival.

Normally I would use something like LookAt, but the character controller (opsive), needs a rotation delta (such as new Vector 3(0,-10,0) to do manual rotation.

I have next to no experience with character movement in my project yet, so i cant really say anything about your approach, but i’m glad i was able to help you for now :slight_smile: