Lookat on local axis

I have an object that must face another on it’s local z axis only. Only the local z euler rotation will be modified.

I’ve seen a few other similar questions, but each answer had a small problem. Here are the three main (incorrect) methods:

Method 1:

Vector3 curRot = transform.localEulerAngles;
curRot.y = 90;
curRot.z = 0;

Vector3 dirToCamera = (camera.position - transform.position).normalized;
float xDir = Quaternion.LookRotation(dirToCamera).eulerAngles.x;
curRot.x = xDir;

transform.localEulerAngles = curRot;

This doesn’t work because xDir is not signed, causing the rotation to only work from one side. On the other, the rotation will be inverted.

Method 2:

// look at camera
Vector3 camRot = camera.position;
Vector3 curRot = transform.position;
Vector3 look = new Vector3(curRot.x, camRot.y, camRot.z);
transform.LookAt(look);

// allign to local 0
Vector3 rot = transform.localEulerAngles;
rot.y = 0;
transform.localEulerAngles = rot;

I’m not exactly sure why this doesn’t work, but it has the same result as Method 1. (Inverted rotation on one side)

Method 3:

Vector3 lookAtPos = camera.position;
Vector3 lookAtPosLocalised = transform.InverseTransformPoint(camera.position);

lookAtPosLocalised.x = 0;

lookAtPos = transform.TransformPoint(lookAtPosLocalised);
transform.LookAt(lookAtPos);

This works perfectly at first, but after a while it becomes “desynced” with the parent rotation. I don’t know what triggers it.

Can anyone help?

I think your first answer might be the best. It only requires a signed angle. Resources for this can be found at this 1.

Once you have the signed angle you can use

var finalAngle = (angle + 360) % 360;

this makes sure the signed angle (which means - for left, + for right rotation) becomes a 0-360 rotation, instead of -180 to 180.

Try this, not sure I got your point

Transform other;

float angle = other.localEulerAngles.z;
transform.rotation = Quaternion.Euler(0, (angle+180.0f),0);