# Trying to rotate a 2D kinematic object along its Z axis when its Y rotation is exactly 180 degrees causes massive rotation swings

I have some code that allows an object to be rotated back and forth on its Z axis, but am having issues when the object has an initial Y rotation of exactly 180 degrees while also trying to rotate it using Rigidbody2D.MoveRotation(). To be specific, the object spazzes out and rotates wildly all over the place.

If I change how I rotate the object by using transform.rotation = someValue, this problem never occurs. Likewise, changing the initial Y rotation to 179.9 or 180.001 alleviates the issue.

It is important for this code to work regardless of the Y rotation, as certain scenes in my game dynamically spawn these rotating objects in a variety of initial rotations. I am using the 180 degree Y rotation to mirror/flip some of the objects.

using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class RotateBackAndForth2D : MonoBehaviour
{
[SerializeField] private float rotationDegrees = 45;
[SerializeField] private float rotationTime = 5;

private new Rigidbody2D rigidbody;

private Quaternion minRotation;
private Quaternion maxRotation;

private void DoRotation()
{
float rotationDelta = Mathf.PingPong(Time.time / rotationTime, 1);
rotationDelta = Mathf.SmoothStep(0, 1, rotationDelta);

Quaternion targetRotation = Quaternion.Slerp(
minRotation,
maxRotation,
rotationDelta);

// Doesn't work sometimes
rigidbody.MoveRotation(targetRotation);

// Always works
// transform.rotation = targetRotation;
}

private void FixedUpdate()
{
DoRotation();
}

private void OnEnable()
{
minRotation = Quaternion.Euler(new Vector3(
transform.eulerAngles.x,
transform.eulerAngles.y,
transform.eulerAngles.z - rotationDegrees));
maxRotation = Quaternion.Euler(new Vector3(
transform.eulerAngles.x,
transform.eulerAngles.y,
transform.eulerAngles.z + rotationDegrees));
}

private void Awake()
{
rigidbody = GetComponent<Rigidbody2D>();
rigidbody.bodyType = RigidbodyType2D.Kinematic;
}
}


## 1 Answer

Your problem is in how you compute your min and max rotations.

Euler angles are half-decent for human data entry, but they are miserable for doing math in because they necessarily contain wrap-around points. Compute your quaternions using quaternion math instead:

minRotation = transform.rotation
* Quaternion.Euler(0 0, -rotationDegrees);

maxRotation = transform.rotation
* Quaternion.Euler(0 0, rotationDegrees);


This takes the object's current rotation and applies a delta of ±rotationDegrees around its local z axis, similar to what you were trying to do with the Euler angles.