Quaternion.LookRoation() don't want to function properly?

Here’s my entire modified SmoothLookAt script.
However, something’s wrong and the turret wont rotate “fully” when the “local mode” is enabled.

var target : Transform;
var local : boolean = true;
var damping = 6.0;
var smooth = true;

var xMin : float = 0;
var xMax : float = 0;

var yMin : float = 0;
var yMax : float = 0;

var zMin : float = 0;
var zMax : float = 0;

var clampX : boolean = false;
var clampY : boolean = false;
var clampZ : boolean = false;


var x : boolean = true;
var y : boolean = true;
var z : boolean = true;

private var xA : float;
private var yA : float;
private var zA : float;

var debug : boolean = false;

var debugBox : GameObject;


@script AddComponentMenu("Camera-Control/Smooth Look At")

function LateUpdate () {
	if (target) {
		if (smooth)
		{
		
		if (local) {
		
			xA = transform.localEulerAngles.x;
			zA = transform.localEulerAngles.y;
			zA = transform.localEulerAngles.z;
			
			// Look at and dampen the rotation
			var rotation : Vector3 = Quaternion.LookRotation(transform.InverseTransformPoint(target.position)).eulerAngles;
			
			if (clampX) rotation.x = Clamp(rotation.x, xMin, xMax);
			if (clampY) rotation.y = Clamp(rotation.y, yMin, yMax);
			if (clampZ) rotation.z = Clamp(rotation.z, zMin, zMax);

			transform.localRotation = Quaternion.Slerp(transform.localRotation, Quaternion.Euler(rotation), Time.deltaTime * damping);
			
			if (!x) transform.localEulerAngles.x = xA;
			if (!y) transform.localEulerAngles.y = yA;
			if (!z) transform.localEulerAngles.z = zA;
			
		}
		else {
		
			xA = transform.localEulerAngles.x;
			zA = transform.localEulerAngles.y;
			zA = transform.localEulerAngles.z;
			
			// Look at and dampen the rotation
			var rotation2 : Vector3 = Quaternion.LookRotation(target.position-transform.position).eulerAngles;

			if (clampX) rotation2.x = Clamp(rotation2.x, xMin, xMax);
			if (clampY) rotation2.y = Clamp(rotation2.y, yMin, yMax);
			if (clampZ) rotation2.z = Clamp(rotation2.z, zMin, zMax);

			//transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(rotation2), Time.deltaTime * damping);
			transform.rotation = Quaternion.Euler(rotation2);
			
			if (!x) transform.localEulerAngles.x = xA;
			if (!y) transform.localEulerAngles.y = yA;
			if (!z) transform.localEulerAngles.z = zA;
					
		}
		
		}
		else
		{
			// Just lookat
		    transform.LookAt(target);
		}
	}
	if (debug) Debug.Log(transform.InverseTransformPoint(target.position).ToString()+"   "+transform.worldToLocalMatrix.MultiplyPoint3x4(target.position));
	if (debugBox) debugBox.transform.localPosition = transform.InverseTransformPoint(target.position);
}

function Start () {

	if (xMin < 0) xMin = 360-Mathf.Abs(xMin);
	if (yMin < 0) yMin = 360-Mathf.Abs(yMin);
	if (zMin < 0) zMin = 360-Mathf.Abs(zMin);
	
	if (xMin == 0  xMax == 0) clampX = false;
	else clampX = true;
	
	if (yMin == 0  yMax == 0) clampY = false;
	else clampY = true;
	
	if (zMin == 0  zMax == 0) clampZ = false;
	else clampZ = true;
	
	
	// Make the rigid body not change rotation
   	if (rigidbody)
		rigidbody.freezeRotation = true;
}

function Clamp (val : float, min : float, max : float) : float {

	if (val < min  val > 180) return min;
	else if (val > max  val < 180) return max;
	else return val;
	
	return val;

}

To clarify things, here goes some lil’ more stuff

The problem is solved thanks to GameVortex who pointed out the error for me :slight_smile:

BTW, here’s the working code

var target : Transform;
var local : boolean = true;
var damping = 6.0;
var smooth = true;

var xMin : float = 0;
var xMax : float = 0;

var yMin : float = 0;
var yMax : float = 0;

var zMin : float = 0;
var zMax : float = 0;

var clampX : boolean = false;
var clampY : boolean = false;
var clampZ : boolean = false;


var x : boolean = true;
var y : boolean = true;
var z : boolean = true;

private var xA : float;
private var yA : float;
private var zA : float;


@script AddComponentMenu("Camera-Control/Smooth Look At")

function LateUpdate () {
	if (target) {
		if (smooth)
		{
		
		if (local  (transform.parent != null)) {
		
			xA = transform.localEulerAngles.x;
			zA = transform.localEulerAngles.y;
			zA = transform.localEulerAngles.z;
			
			// Look at and dampen the rotation
			var rotation : Vector3;
			
			rotation = Quaternion.LookRotation(transform.parent.InverseTransformPoint(target.position)).eulerAngles;
			// or better rotation = Quaternion.LookRotation(transform.parent.InverseTransformDirection(target.position - transform.position)).eulerAngles;
			
			
			if (clampX) rotation.x = Clamp(rotation.x, xMin, xMax);
			if (clampY) rotation.y = Clamp(rotation.y, yMin, yMax);
			if (clampZ) rotation.z = Clamp(rotation.z, zMin, zMax);

			transform.localRotation = Quaternion.Slerp(transform.localRotation, Quaternion.Euler(rotation), Time.deltaTime * damping);
			
			//transform.localRotation = Quaternion.Euler(rotation);
			
			if (!x) transform.localEulerAngles.x = xA;
			if (!y) transform.localEulerAngles.y = yA;
			if (!z) transform.localEulerAngles.z = zA;
			
		}
		
		else {
		
			xA = transform.localEulerAngles.x;
			zA = transform.localEulerAngles.y;
			zA = transform.localEulerAngles.z;
			
			// Look at and dampen the rotation
			var rotation2 : Vector3 = Quaternion.LookRotation(target.position-transform.position).eulerAngles;

			if (clampX) rotation2.x = Clamp(rotation2.x, xMin, xMax);
			if (clampY) rotation2.y = Clamp(rotation2.y, yMin, yMax);
			if (clampZ) rotation2.z = Clamp(rotation2.z, zMin, zMax);

			//transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(rotation2), Time.deltaTime * damping);
			transform.rotation = Quaternion.Euler(rotation2);
			
			if (!x) transform.localEulerAngles.x = xA;
			if (!y) transform.localEulerAngles.y = yA;
			if (!z) transform.localEulerAngles.z = zA;
					
		}
		
		}
		else
		{
			// Just lookat
		    transform.LookAt(target);
		}
	}
}

function Start () {

	if (xMin < 0) xMin = 360-Mathf.Abs(xMin);
	if (yMin < 0) yMin = 360-Mathf.Abs(yMin);
	if (zMin < 0) zMin = 360-Mathf.Abs(zMin);
	
	if (xMin == 0  xMax == 0) clampX = false;
	else clampX = true;
	
	if (yMin == 0  yMax == 0) clampY = false;
	else clampY = true;
	
	if (zMin == 0  zMax == 0) clampZ = false;
	else clampZ = true;
	
	
	// Make the rigid body not change rotation
   	if (rigidbody)
		rigidbody.freezeRotation = true;
}

function Clamp (val : float, min : float, max : float) : float {

	if (val < min  val > 180) return min;
	else if (val > max  val < 180) return max;
	else return val;
	
	return val;

}

You wanted me to elaborate a bit on the InverseTransformDirection here, so here I am. =)

The reason why I said that a Direction would be better is because unlike LookAt the LookRotation requires a Direction to face instead of a point to face. In your script supplying a point works probably because your turret is in the center (0,0,0) of the parents coordinate system, so a point in that space is therefore also a direction for the turret. If you move your turret away from the center it would no longer face the correct direction, but rather face an imaginary point offset by the same amount the turret has been offset from the center.

Calculating the correct local direction with InverseTransformDirection will solve that problem as we also take into account the position of the turret.

Hope this makes sense, I tend to ramble a bit. =P

Now that makes some sense finally!

Thanks for your kind time :slight_smile:

Regards