Hello,
I am not sure how to limit an objects degree of angle in my case 25 degrees up & 15 degrees down, Is there anyway for it to be implemented into this script?
var goTarget : GameObject;
var maxDegreesPerSecond : float = 60.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);
}
I have tried a few things but i just get errors popping up left right center, Any help would be greatly appreciated, Thanks.
2 Answers
2
This code won’t work: you’re messing localRotation with global rotation, and the Vector3 math that calculates v3Aim doesn’t seem to produce something useful.
Limiting rotation angles is a complex job: you can’t rely on the Euler angles because at certain sectors they can switch to weird (although correct) combinations.
A possible solution is to decompose the desired direction into vertical and horizontal components, limit the vertical direction and join them into a limited direction vector - like this:
var maxAngle: float = 25;
var minAngle: float = -15;
function Update () {
// get the normalized target direction:
var dir = (goTarget.transform.position - transform.position).normalized;
var maxSin = Mathf.Sin(maxAngle * Mathf.Deg2Rad); // get sine of max angle
var minSin = Mathf.Sin(minAngle * Mathf.Deg2Rad); // get sine of min angle
var sine = Mathf.Clamp(dir.y, minSin, maxSin); // get the clamped angle sine
var cos = Mathf.Sqrt(1 - (sine * sine)); // calculate the cosine with Pythagoras
// compound the new direction vector:
dir = Vector3(dir.x, 0, dir.z).normalized * cos; // set the horizontal direction...
dir.y = sine; // and set the vertical component
qTo = Quaternion.LookRotation(dir, Vector3.up); // look at the new direction
transform.rotation = Quaternion.RotateTowards(transform.rotation, qTo, maxDegreesPerSecond * Time.deltaTime);
}
Notice that this code takes advantage of the fact that in a normalized vector the Y component is numerically equal to the sine of the elevation angle: we can limit it to the desired range and create a new direction vector.
Note when posting questions like this one and using code borrowed from another question, please make a reference to the original code. This 1) helps other such as @aldonaletto have the full context for an answer, 2) gives credit to the original author, and 3) makes it more likely that the original author will recognize the code and give you an answer. In this case, you borrowed the code from my answer here:
http://answers.unity3d.com/questions/388185/make-the-turret-automatically-rotate-to-look-at-wh.html
Note this code only works if you keep the turret parallel to the XZ plane. So if your tank is roaming over hills, you will need a different solution. As for limiting rotation, you can do it this way:
#pragma strict
var goTarget : GameObject;
var maxDegreesPerSecond : float = 30.0;
var maxDegrees = 25.0;
var minDegrees = -15.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;
var angle = Mathf.Atan2(v3Aim.y, v3Aim.z) * Mathf.Rad2Deg;
if (angle > maxDegrees) {
v3Aim.y = Mathf.Tan(maxDegrees * Mathf.Deg2Rad) * v3Aim.z;
}
if (angle < minDegrees) {
v3Aim.y = Mathf.Tan(minDegrees * Mathf.Deg2Rad) * v3Aim.z;
}
qTo = Quaternion.LookRotation(v3Aim);
transform.localRotation = Quaternion.RotateTowards(transform.localRotation, qTo, maxDegreesPerSecond * Time.deltaTime);
}
The idea is that if the angle of the target is outside of your range, the ‘y’ value of the ‘v3Aim’ is recalculated to bring it up or down so that the angle is within range.
See if this helps: [http://docs.unity3d.com/Documentation/ScriptReference/Mathf.Clamp.html][1] [1]: http://docs.unity3d.com/Documentation/ScriptReference/Mathf.Clamp.html
– getyour411@getyour411 Thanks for the reply, I implemented the Mathf.Clamp on the rotation but its not having any effect, Maybe i am putting it in the wrong place or i am using the wrong code. transform.rotation.x = Mathf.Clamp(transform.rotation.x, -15, 25);
– BritishGuyAny Ideas please?
– BritishGuyInstead of using Quaternion.RotateTowards(), try [Quaternion.Euler()][1]. This will require some other modification of your script, but I had the same problem once upon a time and this is how I solved it. [1]: http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.Euler.html
– Quillicit