Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Angle between two objects in 2D space

Discussion in 'Scripting' started by VCCGeek, Jan 4, 2010.

  1. VCCGeek

    VCCGeek

    Joined:
    Nov 17, 2009
    Posts:
    89
    This is both a question and an answer.

    So I've been trying to figure out how to get the angle between two objects that are assumed to be on the same plane. I have a character that the player has given a destination to walk to. I want that character to turn towards that destination, but I don't want him to lean back as he walks if it's uphill (that's not realistic -- one is more likely to lean forward).

    I got a workable solution, but it seems a bit clunky. I also tried a function juggling quaternions a bit, but it came out rather comical. Does anyone know a more elegant way of doing this? I'm sort of thinking built-in functions here.

    If it's helpful to anyone else, here's the function:

    Code (csharp):
    1.  
    2. public float GetAngle(float X1, float Y1, float X2, float Y2) {
    3.  
    4.         // take care of special cases - if the angle
    5.         // is along any axis, it will return NaN,
    6.         // or Not A Number.  This is a Very Bad Thing(tm).
    7.         if (Y2 == Y1) {
    8.             return (X1 > X2) ? 180 : 0;
    9.         }
    10.         if (X2 == X1) {
    11.             return (Y2 > Y1) ? 90 : 270;
    12.         }
    13.        
    14.         float tangent = (X2 - X1) / (Y2 - Y1);
    15.         // convert from radians to degrees
    16.         double ang = (float) Mathf.Atan(tangent) * 57.2958;
    17.         // the arctangent function is non-deterministic,
    18.         // which means that there are two possible answers
    19.         // for any given input.  We decide which one here.
    20.         if (Y2-Y1 < 0) ang -= 180;
    21.  
    22.  
    23.         // NOTE that this does NOT need to be normalised.  Arctangent
    24.         // always returns an angle that is within the 0-360 range.
    25.        
    26.  
    27.         // barf it back to the calling function
    28.         return (float) ang;
    29.    
    30.     }
    31.  
     
    PFNienow and MrGreenish like this.
  2. magwo

    magwo

    Joined:
    May 20, 2009
    Posts:
    402
    You could use this instead:
    http://unity3d.com/support/documentation/ScriptReference/Vector3.Angle.html

    Note that these are vectors, so basically what you want to do, I'm guessing, in your case is:

    Vector3.Angle(Vector3.up, obj2.transform.position - obj1.transform.position);

    or something similar.

    The "angle between two objects" is essentially a nonsensical statement even if the objects are in a plane. You probably implicitly think of it in relation to one of the coordinate system base vectors.
     
    czDeadInside likes this.
  3. VCCGeek

    VCCGeek

    Joined:
    Nov 17, 2009
    Posts:
    89
    Ok, let me make it a bit more proper: The angle I would need to rotate my character, on the Y axis, from zero in order to be facing a specific point on the same plane.

    I do think that's what I need, though. I knew there had to be an easier way. :)

    Thanks!
     
  4. MrGreenish

    MrGreenish

    Joined:
    Oct 20, 2019
    Posts:
    34
    Thank you so much for this! I had a terrible headache trying to figure this out. I added this to display the way I wanted before returning the variable
    Code (CSharp):
    1.  
    2. ang -= 90;
    3. ang = -ang;
    4. // barf it back to the calling function
    5. return (float)ang;
    It's giving a value that is 90 degrees of and it makes more sense to me to get a positive value rather than a negative.
     
    PFNienow likes this.