Rotating Turret Base and Barrel

I have looked all over and can’t find anything that works for me. The closest I got to seperately rotating the base and barrel of a turret was something I found on here from a few years back.

But it makes them all jittery and they don’t look anywhere near their target. Just a mess.
And I just can’t figure it out :frowning:

I have a turret, on a ship. It has a base and a barrel object. The script I found buried in here I converted from JS to C#:

using UnityEngine;
using System.Collections;

public class PSK_Turret : MonoBehaviour {

	public Transform turretBase;
	public Transform turretBarrel;

	public float baseRotateSpeed;
	public float barrelRotateSpeed;

	public Transform target;
	

	// Update is called once per frame
	void Update () {
		if (target != null) {
			Quaternion tmpBaseRot = turretBase.localRotation;
			Vector3 targetPointTurret = (target.position - turretBase.position); //get normalized vector toward target
			Quaternion targetRotationTurret = Quaternion.LookRotation (targetPointTurret, turretBase.up); //get a rotation for the turret that looks toward the target
			turretBase.rotation = Quaternion.Slerp(transform.rotation, targetRotationTurret, Time.deltaTime * baseRotateSpeed); //gradually turn towards the target at the specified turnSpeed
			turretBase.localRotation = Quaternion.Euler( tmpBaseRot.eulerAngles.x, turretBase.localRotation.eulerAngles.y, tmpBaseRot.eulerAngles.z); //reset x and z rotations and only rotates the y on its local axis

			Quaternion tmpBarrelRot = turretBarrel.localRotation; //preserves the local rotation since we only want to rotate on local x axis
			Vector3 targetPointBarrels = (target.position - turretBarrel.position); //get a normalized vector towards the target
			Quaternion targetRotationBarrels = Quaternion.LookRotation (targetPointBarrels, turretBarrel.up); //get a rotation that looks at the target
			turretBarrel.rotation = Quaternion.Slerp(turretBarrel.rotation, targetRotationBarrels, Time.deltaTime * barrelRotateSpeed); //gradually turn towards the target as the specified turnSpeed
			turretBarrel.localRotation = Quaternion.Euler( turretBarrel.localRotation.eulerAngles.x, tmpBarrelRot.eulerAngles.y, tmpBarrelRot.eulerAngles.z); //reset y and z rotations and only rotates the x on its local axis
		}
	}

}

Does not work though :confused: Does anybody have a good easy solution for aiming a turret properly at a target? I know I can use LookAt to make the whole thing rotate at the target… but that doesnt work right either. I did get a good base rotation with LookAt, but the turret itself had to be upright, if I rotated it sideways it would rotate itself back flat…

Any help would be greatly appreciated. Trying to figure this out has been killing me.

If you turrent is axes aligned, you can do something simple like this the two scripts here:

But if your turret will have arbitrary rotations like if it was on the side of a space ship or on a tank running across a terrain, then go to this answer:

…and open up the comment on my answer. You will find a short script that handles both rotations.

Unfortunately, both scripts are Javascript. If you have problems translating to C#, let me know.

It works very well. I do get some points where the barrel will aim down through the base… I’m not sure why. Maybe because its on a ship that moves freely in 3d space. But I could simply add some code that won’t allow it to shoot itself. And it gives me something to go on :slight_smile: thank you much

here is some code

Quaternion tmpRotation = turretGO.transform.localRotation;

    Vector3 targetPointTurret = (lookAtTarget.transform.position - turretGO.transform.position).normalized;

    Quaternion targetRotationTurret = Quaternion.LookRotation(targetPointTurret, turretGO.transform.up);

    turretGO.transform.rotation = Quaternion.Slerp(transform.rotation, targetRotationTurret, 1f);

    //replace 1f = Time.deltaTime * turnSpeed if u want a delay time

    turretGO.transform.localRotation = Quaternion.Euler(tmpRotation.eulerAngles.x, turretGO.transform.localRotation.eulerAngles.y, tmpRotation.eulerAngles.z);

    /////////////////////////////////////////

    tmpRotation = gunGO.transform.localRotation;

    Vector3 targetPointBarrels = (lookAtTarget.transform.position - gunGO.transform.position).normalized;

    Quaternion targetRotationBarrels = Quaternion.LookRotation(targetPointBarrels, transform.up);

    gunGO.transform.rotation = Quaternion.Slerp(gunGO.transform.rotation, targetRotationBarrels, 1f);

    //replace 1f = Time.deltaTime * turnSpeed if u want a delay time

    gunGO.transform.localRotation = Quaternion.Euler(gunGO.transform.localRotation.eulerAngles.x, tmpRotation.eulerAngles.y, tmpRotation.eulerAngles.z);