- Home /
Calc angle.
I need to be calculated the angle between normal to the ground and the one has my object. Take a look:
I've made that script:
using UnityEngine;
using System.Collections;
public class PlaneBehaviour : MonoBehaviour
{
void Update()
{
//Get values
float horizontal = Input.GetAxis("Horizontal") * Time.deltaTime;
float vertical = Input.GetAxis("Vertical") * Time.deltaTime;
//Apply
transform.Translate((Vector3.forward * 100) * Time.deltaTime);
transform.Rotate(vertical, 0, horizontal);
float angle = -((Vector3.Angle(Vector3.up, transform.forward)) - 90);
Debug.Log(angle);
}
}
With my code the angle is being calculated well is I move my object up and down. Problem comes when I rote my object. Instead of have the angle marked in red, I get 90 degrees (marked in blue):
Cheers!!
I'm not sure what you are asking, but note that Vector3.Angle is not signed, so your calculation will be incorrect for some rotations. If you describe what you are trying to do with the angle, someone on the list can likely give you a solution.
So please we need to know some more details, as you told "The angle is being calculated well except when I rotate my object has been rotated horizontally:" So as you run the game you are getting the accurate angle? but why to do
float angle = -((Vector3.Angle(Vector3.up, transform.forward)) - 90);
and not just simply
float angle = Vector3.Angle(Vector3.up, transform.forward);
And when you rotate horizontally, you mean around y axis right?
I've upgraded the question and the pictures. I hope now is clearer.
Clearer, but still not enough for me to write an answer. Vector3.Angle will return an unsigned angle representing the shortest distance between the two vectors, so it does not always measure what you want it to measure. Rather than focus on how to get your angle right, you might want to describe the problem you are trying to solve by calculating the angle. There are many different ways of dealing with rotations in Unity.
I've an object that is always moving forward, it can rotate and move up and down over the new position (think in something like a spaceship).
What I want to know is how much has changed the trajectory (up and down from my object) in a period of time.
That could be a good example:
Answer by hoy_smallfry · Feb 22, 2013 at 06:15 PM
This looks like a job for... DA DA DA!
The vector dot product!!
The the result of the dot product between two vectors A and B (A · B) is equal to the cosine of the angle between them (cos(θ)) multiplied by the magnitude of vector A (|A|), or:
|A|cos(θ) = A · B
Then all you have to do is solve for θ, the angle between the A and B:
|A|cos(θ) = A · B
cos(θ) = (A · B) / |A|
θ = acos((A · B) / |A|)
Unity has a dot product function, a vector magnitude function, and a arc cosine (inverse cosine) function, so that you can do this in code. The result is in radians, so if you want degrees Unity also provides a function that converts radians to degrees.
Edit:
I realized that Vector.Angle most likely does this already, so I looked over your code some more, and I realized that you are probably getting 90 degrees in the second image because you are using Vector3.up in this line of code:
float angle = -((Vector3.Angle(Vector3.up, transform.forward)) - 90);
According to the documentation, Vector3.up is a constant that represents (0, 1, 0). So your second picture is wrong. The actual vectors being used for the calculations are these:
and that angle between them is 90 degrees. The math is correct; it's your expectation that isn't. If you wanted it to detect the shortest angle among all axes, that's another thing.
Of course, maths are right. I'm using Vector3.up when I would need it rotated the same than the object. I know that Vector3.up is a constant. In that case I would need a unitary vector rotated 90º