I am using a chain of objects that all follow each other in sequence. It behaves similarly to a snake. The game is done in 2D. The issue though is that when rotating each object to face the next, the objects flip around at the transition between 180 and -180. Does anyone know what the issue could be? I am using this to make them face each other smoothly to create a snake-joint effect:
transform.Rotate ((FollowTarget.transform.rotation.eulerAngles - transform.rotation.eulerAngles) / 25);
Any help is much appreciated. I tried looking it up, and found this page: How to prevent transform.Rotate from oddly flipping other axis... - Questions & Answers - Unity Discussions Their problem matches the issue I am having precisely; however, it is useless to me as the page and answer provides no means of solving it.
EDIT:
Correction, this is happening between the transition from 0 to 360 degrees, not -180 to 180. Shouldn’t make a difference.
EDIT:
I know what is happening. When the head makes the movement from 0 to 360 degrees, the segments get the results as if the head had rotated a full 360 in the other direction and attempt to follow it. However, I have no idea how to solve it. I tried multiple solutions involving rotating the segments with the head, but nothing worked. The only way for me to fix this is to make the segments stretch out in a straight line to counter the effects of the head, but this is just as bad and terrible looking as the problem it is trying to solve.
Well you can fix it in a number of ways (as always).
If you really want to keep using Eulerian angle representation then you could use Mathf.LerpAngle
or Mathf.MoveTowardsAngle
. These functions take into account that 360 and 0 are the same value, and will go the shortest distance taking that into account, e.g. MoveTowardsAngle(350, 0, 5) should equal 355.
If you are happy to move to using Quaternions (which are generally better for avoiding this kind of issue once you get your head around them) you can use similar functions:
transform.rotation = Quaternion.RotateTowards(transform.rotation, FollowTarget.transform.rotation, 5 * Time.deltaTime);
or to recreate the smoothing of your current solution you could try:
transform.rotation = Quaternion.Lerp(transform.rotation, FollowTarget.transform.rotation, 0.5f);
The 0.5f value means that it will always halve the distance between one rotation and the other, meaning it will appear to slow down in ‘rate’ of rotation as it gets close to the desired point.
As a completely different solution, you could make each segment LookAt the segment in front of it, which might be the easiest!
transform.LookAt(FollowTarget.transform.position);
@notpresident35 You are rotating object in local space. Sometime local rotate funny because of parent.
Read the document rotate in World space might help(remember there are 3 axis in eulerAngles).
Here is another solution of flipping object just by set local axis scale to -1.
Not really certain but you could test it out - calling transform.rotate rotates the object around all three axis. Perhaps you might want to lock its rotation around the x and y axis only if you’re working in 2D space?