Strange behaviour when using a new quaternion constructed from current rotation VS using it directly

Hi all,

I was working on an enemy and got a bit confounded with quaternions. I felt like I was missing something impotant, so I wrote the following code as a simple test, to make my enemy face towards the player character by rotating around the y-axis.

``````quaternion lookDir = quaternion.LookRotation(dir, new float3(0f, 1f, 0f));
quaternion targetRotation = math.slerp(lt.ValueRO.Rotation, lookDir, 4f * dt);

lt.ValueRW.Rotation = targetRotation;
``````

so far so good. Now I would expect the following code to do the exact same thing. I take the current rotation’s euler-y value, construct a new quaternion from it, and use that instead:

``````float3 euler = math.EulerXYZ(lt.ValueRO.Rotation);

quaternion qfacing = quaternion.EulerXYZ(new float3(0f, euler.y, 0f));
quaternion lookDir = quaternion.LookRotation(dir, new float3(0f, 1f, 0f));
quaternion targetRotation = math.slerp(qfacing, lookDir, 4f * dt);

lt.ValueRW.Rotation = targetRotation;
``````

…except now the enemy only faces the player if the angle between the two is `[-tau, tau]`, any angle outside that range, the enemy does not rotate.

Does anyone have any idea what could be causing this?

(The reason I’m trying to (de)construct my quaternions this way is because I want a different rotation speed between my enemy’s “facing rotation” and “tilt rotation”. And yes, I am using a proper `RotateTowards()` method instead of `slerp`; I just wanted to create an as-minimal-as-possible example.)

Thanks!

Just compute the Euler angles following Unity’s default rotation order, ZXY, so call `math.EulerZXY` instead. For a rotation with only yaw (no pitch/roll), rotation orders XYZ and ZYX end up giving x=pi, z=pi, y=something else at certain rotations, such that isolating the y value to construct a quaternion from Euler angles doesn’t work. Also, tau = 2pi i.e. one full rotation, so a range of [-2pi, 2pi] doesn’t make sense. I presume you mean 0.5pi.