Here’s the idea: I want to create a tank with a turret, which does not turn as I rotate it around the Y axis with my mouse, but rather, make it aim at where I am pointing the camera at.
For example, I have a turret, and I use the camera to look at a point on a cube. I want the turret to gradually rotate on its own Y axis to that direction until it faces this point on the cube. Same goes for rotating the gun so it aims at this point in preparation to fire.
How can I do this? If possible please keep the script as simple as possible because I am using this as a learning material and I am currently rather bad at Java Scripting.
I’m not exactly sure what you want from your description, but here are two scripts that combined will have a gun on a turret pointing at a specified game object. As the game object moves, it will track the object. Tracking speed is controlled by the maxDegreesPerSecond parameter. For smaller values and/or larger target movements, the gun will lag behind the target. The gun must be a child object of the turret, and the gun barrel must point forward (i.e. down the Z axis). In the inspector, drag the target object to the GoTarget parameter in both scripts.
— Turret script —
var goTarget : GameObject;
var maxDegreesPerSecond : float = 30.0;
private var qTo : Quaternion;
function Start () {
qTo = goTarget.transform.localRotation;
}
function Update () {
var v3T = goTarget.transform.position - transform.position;
v3T.y = transform.position.y;
qTo = Quaternion.LookRotation(v3T, Vector3.up);
transform.rotation = Quaternion.RotateTowards(transform.rotation, qTo, maxDegreesPerSecond * Time.deltaTime);
}
— Gun Script —
var goTarget : GameObject;
var maxDegreesPerSecond : float = 30.0;
private var qTo : Quaternion;
function Start () {
qTo = goTarget.transform.localRotation;
}
function Update () {
var v3T = goTarget.transform.position - transform.position;
var v3Aim : Vector3;
v3Aim.x = 0.0;
v3Aim.y = v3T.y;
v3T.y = 0.0;
v3Aim.z = v3T.magnitude;
qTo = Quaternion.LookRotation(v3Aim, Vector3.up);
transform.localRotation = Quaternion.RotateTowards(transform.localRotation, qTo, maxDegreesPerSecond * Time.deltaTime);
}
Here’s some C# code I use for spaceship turrets. I feel this could be simplified a bit but I was never able to get it to work without saving the local rotation and reapplying them to the axes I don’t want to rotate. Works no matter how the vehicle is oriented.
The barrels need to be a child of the rotating turret base. The script is a component of the turret base. This code is in the update function (I declare all the variables beforehand to reduce garbage collection).
The turret will traverse on the local Y-axis, and the barrels will pitch on the local X-axis.
//rotate turret
tmpRotation = transform.localRotation; //preserves the local rotation since we only want to rotate on local Y axis
leadTargetPosition = FirstOrderIntercept(transform.position,Vector3.zero,laserParticleLeft.particleEmitter.localVelocity.z,target.transform.position,target.rigidbody.velocity);
targetPointTurret = (leadTargetPosition - transform.position).normalized; //get normalized vector toward target
targetRotationTurret = Quaternion.LookRotation (targetPointTurret, parent.transform.up); //get a rotation for the turret that looks toward the target
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotationTurret, Time.deltaTime * turnSpeed); //gradually turn towards the target at the specified turnSpeed
transform.localRotation = Quaternion.Euler( tmpRotation.eulerAngles.x, transform.localRotation.eulerAngles.y, tmpRotation.eulerAngles.z); //reset x and z rotations and only rotates the y on its local axis
//rotate barrels
tmpRotation = barrels.transform.localRotation; //preserves the local rotation since we only want to rotate on local x axis
targetPointBarrels = (leadTargetPosition - barrels.transform.position).normalized; //get a normalized vector towards the target
targetRotationBarrels = Quaternion.LookRotation (targetPointBarrels, parent.transform.up); //get a rotation that looks at the target
barrels.transform.rotation = Quaternion.Slerp(barrels.transform.rotation, targetRotationBarrels, Time.deltaTime * turnSpeed); //gradually turn towards the target as the specified turnSpeed
barrels.transform.localRotation = Quaternion.Euler( barrels.transform.localRotation.eulerAngles.x, tmpRotation.eulerAngles.y, tmpRotation.eulerAngles.z); //reset y and z rotations and only rotates the x on its local axis
Thanks DarthDisembowel edited some word:D
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);