I think Peter is right with the way Vector2.Angle is working: It is doing a dot product between the two vectors, and this can only tell you the angle from 0 to 180 just like he said. You can use a cross product between the two vectors (as Vector3s with a z value of 0) to determine which direction the angle is heading. Try this:
Vector2 fromVector2 = new Vector2(0, 1);
Vector2 toVector2 = new Vector2(-1, 0);
float ang = Vector2.Angle(fromVector2, toVector2);
Vector3 cross = Vector3.Cross(fromVector2, toVector2);
if (cross.z > 0)
ang = 360 - ang;
Debug.Log(ang);
I think this will work for any two vectors.
Edit: Updated to use the implicit cast.
Thanks Sigil, it works perfectly!! I just modify the cross.z>0 to cross.z<0 cause (I guess) the default angle direction is counter-clockwise
Just for the sake of saving writing, you can cast from Vector2 to Vector3 implicitly. You can pass the two vector2's directly into Vector3.Cross() and save yourself the time of creating a new vector3 explicitly.
One guess is that its easier to keep things straight if you clamp angles between 0 and 180 degrees. Then you can express every angle from one side or the other. You can figure out which side your angle is with cross products. There’s a forum thread on it somewhere.
I also have some speculation as to why this is. This is a guess because I don’t know how the function works internally, but I guess it uses an inverse trig function. I’m not sure which one, but I’d use arccos because its principle domain is from 0 to 180 degrees.
arccos ( (V1 • V2) / ( |V1| |V2|) ) = Angle.
Since arccos is defined from 0 to 180, the only values it can return are from 0 to 180.
Note: that is just speculation. I would be interested to here how Vector2.Angle() actually works
Thanks Peter, that is it, Sigil have posted the "Cross Product".
Just because you ask for it, this is how Vector3.Angle is defined: public static float Angle(Vector3 from, Vector3 to) { return Mathf.Acos(Mathf.Clamp(Vector3.Dot(from.normalized, to.normalized), -1f, 1f)) * 57.29578f; } ps just in case it's not obvious 57.29578f == (180/PI) to convert radians to degree. pps: the function looks exactly the same for Vector2
float Angle( Vector2 a, Vector2 b ) {
var an = a.normalized;
var bn = b.normalized;
var x = an.x * bn.x + an.y * bn.y;
var y = an.y * bn.x - an.x * bn.y;
return Mathf.Atan2(y, x) * Mathf.Rad2Deg;
}
older similar question: http://answers.unity3d.com/questions/38371/getting-angle-0-359-between-two-game-objects.html
– cregox