LookAt To Only Rotate on Y Axis - How?

Hello,

I have a LookAt function on my turret, and right now it works fine, the turret rotates itself to look at its target, but how would I only allow my turret to rotate on the Y axis, right now it also tilts too.

This is my lookat function:

var rotation = Quaternion.LookRotation(target.position - transform.position);
            transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);

Taken from the SmoothLookAt script (assets)

Thanks.

Hi All,

While Michael’s above code should work. Manually modifying transform.rotation is not the recommended Unity way to rotate an object.

It is in fact possible to limit the axes which rotate using transform.LookAt(). Please see the following code which limits rotation to the Y axis only:

Vector3 targetPostition = new Vector3( target.position.x, 
                                       this.transform.position.y, 
                                       target.position.z ) ;
this.transform.LookAt( targetPostition ) ;

At a basic level the LookAt() function calculates rotational values for the object you want to rotate (transform) based on the positional values of the object you want to look at (target). The key benefit to LookAt() is that it ensures your transform always faces the target, calculating the necessary rotational values accordingly.

All the above code is really saying is: “calculate the rotational values for the transform based on the target’s X and Z positions (horizontal plane), but the target’s Y position will always be the same as mine.” E.g. the same height as me. The resulting calculation forces the transform to face in the direction of the target but believes the target is at the same height of the transform. Thus preventing vertical rotation.

This is my interpretation of it anyway. If anyone can provide further detail I would really welcome it!

You just need to make sure you're giving planar positions, i.e.:

var lookPos = target.position - transform.position;
lookPos.y = 0;
var rotation = Quaternion.LookRotation(lookPos);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);

Take a look at this (LookAt locked at Y-axis but in local space - Unity Answers)

In summary for those of us that want to rotate for example a turret around its local y axis when said turret can be mounted at an angle in world space the above solution does the trick.

What its doing is similar but projects the point on a plane local to the turret or whatever you are rotating. Below is my implementation for a turret system.

//Project to plane
        float distanceToPlane = Vector3.Dot(selfTransform.up, position - selfTransform.position);
        Vector3 pointOnPlane = position - (selfTransform.up * distanceToPlane);

        selfTransform.LookAt(pointOnPlane, selfTransform.up);

I had similar problem and every answers what i found here arent entirely true, becouse other answers here change X and Z axis too. If you want change only Y axis and do not interfere with others axis, you need do something like this:

var lookPos = target.transform.position - transform.position;
            Quaternion lookRot = Quaternion.LookRotation(lookPos);
            lookRot.eulerAngles =new Vector3(transform.rotation.eulerAngles.x, lookRot.eulerAngles.y, transform.rotation.eulerAngles.z);
            transform.rotation = Quaternion.Slerp(transform.rotation, lookRot, Time.deltaTime * speedOfrotation);

Now objects change only Y axis and can rotate by physics on other Axes.

My first post on this site, excuse me for the HUGE bump!

I’d like to expand on @Revolver2k’s post by providing a JS example for people still getting to grips with coding.

#pragma strict
var target : Transform;

function Update () {
var targetPostition : Vector3  = new Vector3(target.position.x, this.transform.position.y, target.position.z);
transform.LookAt(targetPostition);
}

This will script will rotate any object you add it to, towards the target you choose (preferably a player).

Hope this helps any passers by.

To look at the object and only rotate at y axis:

void Update() 
{
    Vector3 lookPos = target.position - transform.position;
    Quaternion lookRot = Quaternion.LookRotation(lookPos, Vector3.up);
    float eulerY = lookRot.eulerAngles.y;
    Quaternion rotation = Quaternion.Euler (0, eulerY, 0);
    transform.rotation = rotation;
}

If anyone is still having issues with a quad billboard not following the main camera without it pitching up or down, here is the code that worked for me. I used this for flags on a terrain that has a slight top down camera. Only the Y axis will rotate on your billboard! =)

NOTE: If your billboards are facing the wrong direction, change the (-posCam) into (posCam).

using UnityEngine;
using System.Collections;

public class RulerFlag : MonoBehaviour {

	public Transform camCam;
	public Vector3 posCam;
	public Quaternion lastPos;
	public float turnSpeed = 20f;

	void Awake () 
	{
		camCam = Camera.main.transform;
	}

	void Update () 
	{
		posCam = camCam.position - transform.position;
		posCam.y = 0;
		lastPos = Quaternion.LookRotation(-posCam);
		transform.rotation = Quaternion.Slerp(transform.rotation,lastPos, Time.deltaTime * turnSpeed);
	}
}

Credit to poster “Mike 3” for the meat of this code. I’ve only filled in the rest of the code so that everyone can copy and past this into a script file and drop it onto any object. Cheers!

Late to the game but here’s how I do it in 3 lines with low overhead:

Vector3 targetPos = targetObject.transform.position - sourceObject.transform.position;
targetPos.y = 0f;
sourceObject.transform.rotation = Quaternion.LookRotation(targetPos);

when not work fine Try this

 if (target != null)
		{
            var lookDir = target.transform.position;
            lookDir.y = transform.position.y;
            transform.LookAt(lookDir, Vector3.up);
        }

Thanks!!!