# Proper way to do Turret Rotation over time?

Digging around I see sample code using many different methods, some seemingly more concise and compact than others. What is the best way to rotate a turret around the Y axis to face a target over x period of time?

EDIT:

This is what I came up with:

``````var targetVector : Vector3 = target.transform.position - turret.transform.position;
var currentVector : Vector3 = turret.transform.rotation * Vector3.forward;
turret.transform.rotation = Quaternion.LookRotation(Vector3.Slerp(currentVector, targetVector, Time.deltaTime));

``````

Seems to work well.

This is what I came up with plucked from my turret class. Hopefully it helps someone.

``````function Update () {
if (isVehicle && stateTracker.state != stateTracker.GROUNDED) {
return;
}

// If enemy is set, turn turret
if (target) {
var clampHorizontal : Vector3 = new Vector3(0, 1, 1);
var clampVertical : Vector3 = new Vector3(1, 0, 1);

// Get the Quaternion value of the turret pointing at the target
var currentTurretRotation : Quaternion = turret.transform.localRotation;
turret.transform.LookAt(target.transform.position);
var targetTurretRotation : Quaternion = turret.transform.localRotation;
turret.transform.localRotation = currentTurretRotation;

// Clamp it to only y axis
currentTurretRotation.eulerAngles = Vector3.Scale(clampHorizontal, currentTurretRotation.eulerAngles);
targetTurretRotation.eulerAngles = Vector3.Scale(clampHorizontal, targetTurretRotation.eulerAngles);

// At what angle will we be aimed at target?
horizontalFiringSolution = targetTurretRotation;

// Rotate it over time
turret.transform.localRotation = Quaternion.RotateTowards(currentTurretRotation, targetTurretRotation, horizontalSeekSpeed);

var currentBarrelRotation : Quaternion;
var targetBarrelRotation : Quaternion;
switch (projectileType) {

case ProjectileTypeEnum.Projectile:
var solutionAngle = CalculateProjectileFiringSolution();

// Not enough range
if (solutionAngle != null) {
verticalFiringSolution = new Quaternion();
verticalFiringSolution.eulerAngles = new Vector3(solutionAngle, 0, 0);

currentBarrelRotation = barrel.transform.localRotation;
targetBarrelRotation = verticalFiringSolution;

barrel.transform.localRotation = Quaternion.RotateTowards(currentBarrelRotation, targetBarrelRotation, verticalSeekSpeed);
}
break;
case ProjectileTypeEnum.Beam:
// Get the Quaternion value of the barrel pointing at the target
currentBarrelRotation = barrel.transform.localRotation;
barrel.transform.LookAt(target.transform.position);
targetBarrelRotation = barrel.transform.localRotation;
barrel.transform.localRotation = currentBarrelRotation;

verticalFiringSolution = targetBarrelRotation;

// Clamp it to only the x axis
currentBarrelRotation.eulerAngles = Vector3.Scale(clampVertical, currentBarrelRotation.eulerAngles);
targetBarrelRotation.eulerAngles = Vector3.Scale(clampVertical, targetBarrelRotation.eulerAngles);

// Rotate it over time
barrel.transform.localRotation = Quaternion.RotateTowards(currentBarrelRotation, targetBarrelRotation, verticalSeekSpeed);
break;
}
}
}

function CalculateMaximumRange() {
var barrelTransform = gunMuzzlePoint.transform.position;

var g = Physics.gravity.y;
var y = barrelTransform.y;
var v = projectileSpeed;
var a = Mathf.Deg2Rad * 45;

var vSin = v * Mathf.Cos(a);
var vCos = v * Mathf.Sin(a);

var sqrt = Mathf.Sqrt(vSin * vSin + 2 * g * y);

return Mathf.Abs((vSin / g) * (vCos + sqrt));
}

function CalculateProjectileFiringSolution() {
var targetTransform =  target.transform.position;
var barrelTransform = gunMuzzlePoint.transform.position;

var y = barrelTransform.y - targetTransform.y;

targetTransform.y = barrelTransform.y = 0;

var x = (targetTransform - barrelTransform).magnitude;
var v = projectileSpeed;
var g = Physics.gravity.y;

var sqrt = (v*v*v*v) - (g * (g * (x*x) + 2 * y * (v*v)));

// Not enough range
if (sqrt < 0) {
return null;
}

sqrt = Mathf.Sqrt(sqrt);

// DirectFire chooses the low trajectory, otherwise high trajectory.
if (directFire) {
return Mathf.Atan(((v*v) - sqrt) / (g*x)) * Mathf.Rad2Deg;
} else {
return Mathf.Atan(((v*v) + sqrt) / (g*x)) * Mathf.Rad2Deg;
}
}

function isTargetInFiringArc() {
GetTarget();

if (target && verticalFiringSolution != null)   {
// How far are we from our firing solution.
var horizontalOffset = Quaternion.Angle(horizontalFiringSolution, turret.transform.localRotation);
var verticalOffset = Quaternion.Angle(verticalFiringSolution, barrel.transform.localRotation);

var distanceToTarget = target ? target.transform.position   - transform.position : Vector3.zero;

if (distanceToTarget.magnitude < minRange) {
return false;
}

// Doesn't work too well looking for 100% perfect accuracy, so substitute .1
if (deviation == 0 && horizontalOffset < .1 && verticalOffset < .1) {
return true;
} else if (horizontalOffset < deviation && verticalOffset < deviation) {
return true;
}
}

return false;
}

``````