Unity中光源旋转时90-270度区间欧拉角读取错误求助
Hey there, let's fix that frustrating rotation bug you're hitting with your light source.
The Root Cause
Your issue boils down to how Unity handles Euler angles: they wrap around in a 0° to 360° cycle. When you rotate your light down past 270°, transform.eulerAngles.x doesn't keep decreasing into negative values—it jumps from 360° back toward 0°. So when you calculate the difference with Mathf.Abs(transform.eulerAngles.x - angle), you're getting a huge, incorrect gap (like 350° - 270° = 80°, instead of the actual shortest path of 20° clockwise). That's why your rotation logic goes haywire until it hits 90° again.
The Fix: Use Unity's Built-In Angle Difference Tool
Unity has a dedicated method to handle exactly this scenario: Mathf.DeltaAngle. It calculates the shortest angle between two values, automatically accounting for the 360° wrap-around. Here's your modified code:
IEnumerator RotateLight() { // Check the shortest angle difference instead of raw Euler values while (Mathf.Abs(Mathf.DeltaAngle(transform.eulerAngles.x, angle)) > 10f) { // Determine which direction to rotate to reach the target faster float rotationDirection = Mathf.DeltaAngle(transform.eulerAngles.x, angle) > 0 ? 1 : -1; transform.Rotate(Vector3.left * rotationDirection * Time.deltaTime * 1, Space.Self); yield return null; } yield break; }
Alternative: Normalize Angles to -180° to 180°
If you prefer to handle the angle wrapping yourself, you can normalize both the current and target angles to a -180° to 180° range first. Add this helper method:
float NormalizeAngle(float angle) { angle %= 360; return angle > 180 ? angle - 360 : angle; }
Then update your rotation check:
IEnumerator RotateLight() { float normalizedTarget = NormalizeAngle(angle); while (Mathf.Abs(NormalizeAngle(transform.eulerAngles.x) - normalizedTarget) > 10f) { float normalizedCurrent = NormalizeAngle(transform.eulerAngles.x); float rotationDirection = normalizedTarget > normalizedCurrent ? 1 : -1; transform.Rotate(Vector3.left * rotationDirection * Time.deltaTime * 1, Space.Self); yield return null; } yield break; }
Quick Note
Also, that Time.deltaTime *1 rotation speed is pretty slow—you might want to bump up that multiplier (like *10 or *20) to make the rotation feel more responsive.
内容的提问来源于stack exchange,提问作者Rich Cat

