Problem with local rotation using Quaternion.LookRotation

I have a compass, which I would like to always head “north” (along the vector (0,0,-1)). To do this I’m using Quaternion.LookRotation(), but something is not right. The dial is pointing where I want it to point, but it is not rotating around it’s initial local Y-axis as I would want it to.

My code right now for this is:

using UnityEngine;
using System.Collections;

public class OrientCompassNorth : MonoBehaviour {
	
	public Vector3 northDirection = new Vector3(0, 0, 1);
	
	// Update is called once per frame
	void LateUpdate () {
		transform.rotation = Quaternion.LookRotation(northDirection,transform.parent.up.normalized);
	}
	
	void OnDrawGizmos ()
	{
    	Gizmos.DrawLine (transform.parent.position, transform.parent.position + transform.parent.up.normalized * 2.0f);
	}
}

Ingame, the compass then looks like this:

alt text

In the scene view, the compass looks like this:

alt text

For me, this means that the up-vector is as it should be, as the line is resembling what i feel is the correct axis to rotate around. But for some reason the dial gets a rotation of (42.3, 2.1, 3.1), which in the editor before runtime is (0, 0, 0)…

It should also be noted that the parent (the rest of the compass) is not aligned with any global planes.

I am looking for any explanation as to why it behaves like this or pointers/general comments of how Quaternion.LookRotation() works if I’m not using it right…

Quaternion.LookRotation works like this:

The z axis will point directly into the direction you provide. The up-vector is just used to determine the rotation around the look-vector.

If you want to keep themoving part always aligned to the frame, you could do it the other way round. Align the moving part in a way that it’s local z (forward) axis points upwards (the normal of your disk) and the local y (up) should be the direction you want to point to.

Now use LookRotation and look along the rotation axis of the framw (the up-vector). The second vector would be your northDirection vector. That way the disk always rotates around the frames up-vector and aligns the y-vector so it “points north”.

Another alternative would be to calculate the angle manually and just assign the local rotation.

// NOT TESTED
Vector3 frameDirection = transform.parent.forward;
float angle = Vector3.Angle(frameDirection, northDirection);
transform.localEulerAngles = new Vector3(0,0,angle); // depends on your rotation axis