Rotation on two axes Issue: Z axis flipping

Hey! I’m working on a racing game atm but this issue has me really stuck.

I am currently still new to Unity and the community so please tell me if I’m not providing enough info for the problem. Any feedback would be appreciated…

The code below is supposed to make the wheel spin based on the velocity and also rotate side to side based on the steering angle.
The wheel spin and the wheel steering works as intended but the problem is, the wheel seems to have its z axis flipped every 360 degree rotation in the x axis.
I don’t understand why this is the case.

    private void Update()
    {
        transform.localRotation = Quaternion.Euler(transform.localRotation.eulerAngles.x, steerAngle, transform.localRotation.eulerAngles.z);

        wheelxRotation = Vector3.Dot(rb.GetPointVelocity(wheelMesh.transform.position), transform.forward) * Time.deltaTime / wheelCircumference * 360;
        Quaternion steerRotation = Quaternion.Euler(wheelMesh.transform.localRotation.eulerAngles.x, steerAngle, wheelMesh.transform.localRotation.eulerAngles.z);
        wheelMesh.transform.localRotation = steerRotation;
        wheelMesh.transform.Rotate(-Vector3.right, wheelxRotation);

        Debug.Log(wheelMesh.transform.localEulerAngles);
    }

Below are the images of the car and the local euler angles of the wheel at that point.

As you can see, the wheel seems to have flipped despite not changing the local z axis.
This flip occurs every 360 degree rotation of the wheel (as it spins).

eulerAngles property is not a reliable source of geometric parametrization. Unity internally works with quaternions and a conversion to Euler angles (not from Euler angles, that’s a different case) can be fiddly and unstable.

You should never use this property for anything more serious than merely eyeballing the values to get a feel for them, because they’ll wrap around whenever they feel like it.

If you want cardinal angles to make reliable logic or clamp the angles and whatnot, you can use Quaternion.SignedAngle(from, to, axis). It’ll return a value in the range [-180…180].

If your angle is on the XZ plane, then you should use Vector3.down as your axis (according to the left-hand rule; a positive angle is counter clockwise when viewed from above), and if you already have rotations the vectors is computed as rotation * Vector3.forward (or simply transform.forward if you have access to the object’s transform) and if you want to get a direction on the fly then you do (targetPoint - sourcePoint).normalized.

Obviously for planar angles you need to make sure that your vectors lie on the same cardinal plane.

You can also use Quaternion.Angle to find an angle betwen two orientations represented by quaternions.

1 Like