I am having an issue where `eulerAngles.y`

is returning a Y rotation value that jumps when I move the character head up and down (X axis).

So when I move the head up (above green line), `eulerAngles.y`

returns 0. But when I move down (below green line), `eulerAngles.y`

returns 180. Keep in mind that moving the head up and down rotates around the X axis.

# Check out the Video (YouTube) explaining the issue.

You can see in the second picture that the local transform and rotation for the head are not default and are a bit rotated.

The Lines coming from the head are just gizmos created as so:

```
Gizmos.color = Color.red;
Gizmos.DrawLine(headTransform.position, headTransform.position + headTransform.up*3);
Gizmos.color = Color.green;
Vector3 forward = headTransform.up;
Gizmos.DrawLine(headTransform.position, headTransform.position + (new Vector3(forward.x, 0, forward.z)*3));
```

I know that `eularAngles`

has a rotation order but how do I get the Y rotation in world space that I can apply to any object and it will point in the same direciton.

My goal is to make the body turn to where the head is looking and have the head counteract the body motion so they are aligned. Although I am having other issues, this is just one I am stuck on why this is happening. When I add the code below, the character just spins around and around.

```
// Make the body rotate to where our head is pointing
bodyTransform.eulerAngles = new Vector3(bodyTransform.eulerAngles.x, headTransform.eulerAngles.y, bodyTransform.eulerAngles.z);
// Counter-act the body by rotating the head back into place
headTransform.eulerAngles = new Vector3(headTransform.eulerAngles.x, bodyTransform.eulerAngles.y, headTransform.eulerAngles.z);
```

## Update:

I tried what @robertbu suggested using `Quaternion.LookRotation`

but I am having trouble getting the desired head, body alignment with the below code. I tried messing with the `upwards`

parameter but nothing works. “Z axis will be aligned with forward and the Y axis with upwards” (Unity documentation) so I am wondering if the transform on the head is messing with it. I am assuming the first part is right because it does turn the body in the direction the head is pointing but I am failing at making the head align with the body to stop it from spinning.

```
// Make the body rotate to where our head is pointing
/* */
Vector3 headForwardDirection = headTransform.up;
headForwardDirection.y = 0f;
Quaternion qTo = Quaternion.LookRotation(headForwardDirection);
bodyTransform.rotation = qTo;
/* */
// Counter-act the body by rotating the head back into place
/* */
Vector3 bodyForwardDirection = bodyTransform.forward;
bodyForwardDirection.y = 0f;
Quaternion qTo2 = Quaternion.LookRotation(bodyForwardDirection);
headTransform.rotation = qTo2;
/* */
```

## Update #2 (Solution):

Just got the project working as expected with the advice of @robertbu of fixing my model head pivot/axis so that Z points forward and Y up. I added a empty/null and parented the head bone.

Here is the script I used to complete the align. It is a combination of a head look and align when moving.

```
using UnityEngine;
using System.Collections;
public class HeadMoveScript : MonoBehaviour {
public Transform headTransform; // Used to rotate the head
public Transform bodyTransform; // Used to rotate the body when head rotation limit reached
public Transform testTransform;
public GameObject cMotorGameObject;
public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityX = 15F;
public float sensitivityY = 15F;
public float minimumX = -360F;
public float maximumX = 360F;
public float minimumY = -60F;
public float maximumY = 60F;
float rotationX = 0F;
float rotationY = 0F;
Vector3 originalForward;
Vector3 originalUp;
Vector3 originalRight;
Quaternion originalRotation;
void Update ()
{
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
// Rotate the body when we reach the rotation limits
if (axes == RotationAxes.MouseXAndY || axes == RotationAxes.MouseX)
bodyTransform.localEulerAngles = new Vector3(bodyTransform.localEulerAngles.x, bodyTransform.localEulerAngles.y + ClampExcess(rotationX, minimumX, maximumX), bodyTransform.localEulerAngles.z);
rotationX = Mathf.Clamp(rotationX, minimumX, maximumX);
rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);
Quaternion xQuaternion = Quaternion.AngleAxis(rotationX, originalUp);
Quaternion yQuaternion = Quaternion.AngleAxis(rotationY, -originalRight);
if (axes == RotationAxes.MouseXAndY)
{
headTransform.localRotation = originalRotation * xQuaternion * yQuaternion;
}
else if (axes == RotationAxes.MouseX)
{
headTransform.localRotation = originalRotation * xQuaternion;
}
else
{
headTransform.localRotation = originalRotation * yQuaternion;
}
/* */
Vector3 moveVelocity = cMotorGameObject.GetComponent<CharacterMotor>().movement.velocity;
// When we start to move forward, make sure we run in the direction our head is pointing
if(Mathf.Abs(moveVelocity.x) > 0 || Mathf.Abs(moveVelocity.z) > 0)
{
// Make the body rotate to where our head is pointing
/* */
Vector3 headForwardDirection = headTransform.forward;
headForwardDirection.y = 0f;
Quaternion qTo = Quaternion.LookRotation(headForwardDirection);
bodyTransform.rotation = qTo;
/* */
// Counter-act the body by rotating the head back into place
/* */
Vector3 bodyForwardDirection = bodyTransform.forward;
bodyForwardDirection.y = 0f;
Quaternion qTo2 = Quaternion.LookRotation(bodyForwardDirection) * Quaternion.AngleAxis(rotationY, -originalRight);
headTransform.rotation = qTo2;
/* */
// Also reset the look rotation of the head
// So we do not jump back after a new loop
rotationX = 0F;
}
/* */
}
void Start()
{
originalForward = headTransform.forward;
originalUp = headTransform.up;
originalRight = headTransform.right;
originalRotation = headTransform.localRotation;
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawLine(headTransform.position, headTransform.position + headTransform.forward*3);
Gizmos.color = Color.green;
Vector3 forward = headTransform.forward;
Gizmos.DrawLine(headTransform.position, headTransform.position + (new Vector3(forward.x, 0, forward.z)*3));
}
// Returns the excess from min or max
float ClampExcess(float value, float min, float max)
{
if(value < min)
return value - min;
else if(value > max)
return value - max;
return 0;
}
}
```