Search Unity

2D Angle between player vector and another GameObject

Discussion in '2D' started by Altera-Interactive, Sep 21, 2017.

  1. Altera-Interactive

    Altera-Interactive

    Joined:
    Oct 9, 2014
    Posts:
    22
    anglebetween.jpg Hi Unity Comunity !

    I read many forums about similar questions but never found a complete answer that suits my needs.

    I want to know the angle between my player vector2 and another GameObject vector2. My final purpose is to chose between two waypoints according to angle between player and these points ( a part i can easily handle).
    The hard part here, for me, is to get an angle that is the real angle between the two objects, even when rotating the player. The others game object never move, they are waypoints. You can see 4 cases to help you understand my problem.

    I'm bad at Math an it's probably the reason why i'm stuck at this problem.... I alors have problems between Euler, Quaternion, Local Eulers...

    I hope you can help me.

    Thanks
     
  2. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    So you're looking for the smaller angle between the player's local X vector, and the direction towards another object.

    Would this do it?
    Code (CSharp):
    1. Transform otherObject;
    2. Transform playerObject;
    3.  
    4. Vector2 playerRight = playerObject.right;
    5. Vector2 towardsOther = otherObject.position - playerObject.position;
    6.  
    7. float angle = Vector2.Angle(playerRight, towardsOther);
     
    Altera-Interactive likes this.
  3. Altera-Interactive

    Altera-Interactive

    Joined:
    Oct 9, 2014
    Posts:
    22
    Hey!
    Seems like a good start. The only problem there : it always give me an angle between 0 and 180 °.
    My idea was to know if player is turning is back on the gameobject (angle >= 180) or not (angle <= 180).

    Maybe there is a totaly other way to do that... I want to only use small calculations and no big things like RayCasting or so...
     
  4. Altera-Interactive

    Altera-Interactive

    Joined:
    Oct 9, 2014
    Posts:
    22
    By the way i replaced player.right by player.up. I wanted angle with player Y Axis (big mistake on my sketch)
     
  5. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    I'm not sure what you mean by that. If the angle is 0 the axis is pointed directly at the object. If the angle is 180 it's facing directly away from the object. 90 degrees would be perpendicular, so >90 is facing away from the object, <90 is facing towards the object.

    You could use SignedAngle to get -180 to 180, where clockwise is positive and counterclockwise is negative.
    https://docs.unity3d.com/ScriptReference/Vector3.SignedAngle.html
     
    Altera-Interactive likes this.
  6. Altera-Interactive

    Altera-Interactive

    Joined:
    Oct 9, 2014
    Posts:
    22
    It works perfectly in fact , after somes tests. As you can see on the following images, when angle with one of the two object is smaller than the other, i can say the player should follow this point. Even when all object are aligned, the one facing the player gives an angle of 0°, the other 180°.
    angle1.png angle2.png
     
    LiterallyJeff likes this.
  7. pansoul

    pansoul

    Joined:
    Jan 8, 2020
    Posts:
    10
    So, what did you use for it? And how did you apply this angle to the object?
     
  8. todddalton

    todddalton

    Joined:
    Jul 26, 2020
    Posts:
    5
    A bit late to the party, but if anyone still needs help, I used the following code after fiddling around with `SignedAngle` and `Angle` methods for both `Vector2` and `Vector3`. They seemed to give a different angle relative to my player object depending on where they were located in the scene. So, assuming all z coords are equal (in my case z == 0 for all game objects) then try calling this method on each `Update()`:

    Code (CSharp):
    1. /// Turns the alien slowly towards the player (if wantsSlerp == true) or immediately towards player
    2.     public void rotateTowardsPlayer(bool wantsSlerp) {
    3.  
    4.         Vector2 my2DPos = new Vector2(transform.position.x, transform.position.y);
    5.         Vector2 player2DPos = new Vector2(playerObject.transform.position.x, playerObject.transform.position.y);
    6.  
    7.         Vector2 direction = player2DPos - my2DPos;
    8.  
    9.         // I wanted the bottom of the 2D sprite to face the player, hence the ` + 90.0f`
    10.         // otherwise without it, the object will angle it's camera right side to the player
    11.         float angle = (Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg) + 90.0f;
    12.  
    13.         if (wantsSlerp) {
    14.             // gives the object a nice slowed approach towards the player
    15.             transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0.0f, 0.0f, angle), Time.deltaTime * 5);
    16.         } else {
    17.             transform.rotation = Quaternion.Euler(0, 0, angle);
    18.         }
    19.     }