Get angle between 2 Vector2's

I’m making a skateboarding game right now and I’m having some problems.

I need to calculate the angle between the start touch position and the end touch position so if angle is ~0(swipe down), it will do a ollie (aka jump), else if angle is ~45(swipe down to the left), it will do a Frontside pop shuveit etc

Vector2.Angle gives me weird results, so please don’t suggest that :stuck_out_tongue_winking_eye:

5 Answers

5

HI,
use the solution from robertbu ,use said you will get the value about -3 ~ 3.

    v2 = v2End - v2Start;
    angle = Mathf.Atan2(v2.y, v2.x)*Mathf.Rad2Deg;

This will make it to -180 ~ 180.

Yeah alright,I realise is a long time ago from the date you asked.Hope this will help some people !

I bookmarked this question so it will definitely be useful one day :)

I made some changes: Vector2 v2 = (mousePosition - initPosition).normalized; float angle = Mathf.Atan2(v2.y, v2.x)*Mathf.Rad2Deg; if(angle < 0) angle = 360 + angle; angle = 360 - angle; Debug.Log("angle: " + angle); Finally you will receive 360 degree around your init Position;

Vector2.Angle is giving your “weird” results because you’re using it wrong – sorry, but it’s true.

That function assumes you have vectors, not positions. Which should be very understandable because you asking the angle between two points is, well, just not possible :wink:

So I guess the point is, what angle do your really want (i.e what’s the point that’s actually relative to these start and end points [is there a center?]) If you know that, then we CAN get the vector for each, and then we CAN used Vector2.Angle!

Oh math <3

I agree is probably getting "weird results" because he is misusing the function, but Vector2.Angle() has a serious issue. It returns an unsigned value and it is the shortest path between the two vectors. It makes it difficult to distinguish between different strokes.

hopefully this image will explain what I'm trying to do: [10400-namnlös.png|10400]

Oh I see. You Could use the angle between the "perfect" stroke and the user's stroke and make it work.

but how do I get the angle?

I keep forgetting about this even though I am fully aware of it as soon as I realise it. Oh math <3

You can calculate the absolute angle using Atan2().

v2 = v2End - v2Start;
angle = Mathf.Atan2(v2.y, v2.x);

I think that makes the assumption that the origin is the relative point...might not be it in all cases. I think he's better off getting the true vectors and then get the angle.

Thanks, it's not 0 to 360 but based on the number that I get (3 to -3) I can calculate when the player does different tricks :)

An alternate solution would be to define a vector for all the different directions you want to distinguish. You could put them in an array to make calculation simple. Then you can do Vector2.Dot() between your stroke vector and all the vectors you have defined. The one with the hightest value will be the one closest to the user's stroke.

This code will debug your direction

109773-iso-directions-600px.png

using UnityEngine;
using System.Collections;

public class AngleDebugger : MonoBehaviour
{
    public Transform target;
    private float Angle;


    void Update()
    {  
        Angle = GetAngle(transform.position,target.position);
        DebugAngle();
    }

    public float GetAngle(Vector2 A,Vector2 B)
    {
        //difference
        var Delta = B - A;
        //use atan2 to get the angle; Atan2 returns radians
        var angleRadians = Mathf.Atan2(Delta.y, Delta.x);

        //convert to degrees
        var angleDegrees = angleRadians * Mathf.Rad2Deg;

        //angleDegrees will be in the range (-180,180].
        //I like normalizing to [0,360) myself, but this is optional..
        if (angleDegrees < 0)
            angleDegrees += 360;

        return angleDegrees;
    }


    void DebugAngle()
    {
        if (Between(60, 120))
            {
            print("N");
        }
        if (Between(240, 300))
        {
            print("S");
        }
        if (Between(330, 360) || Between(0, 30))
        {
            print("E");
        }
        if (Between(150, 210))
        {
            print("W");
        }


        if (Between(120, 150))
        {
            print("NW");
        }
        if (Between(30, 60))
        {
            print("NE");
        }

        if (Between(210, 240))
        {
            print("SW");
        }
        if (Between(300, 330))
        {
            print("SE");
        }


    }

    bool Between(float A,float B)
    {
        if(Angle < B && Angle > A)
        {
            return true;
        }
        return false;
    }

}

you can use this functions:

    public static float AngleBetween2Vector2right(Vector2 pos, Vector2 target)
    {
        if (target.y < pos.y)
            return Vector2.Angle(Vector2.right, target - pos) * -1.0f;
        else
            return Vector2.Angle(Vector2.right, target - pos);
    }
    public static float AngleBetween2Vector2Up(Vector2 pos, Vector2 target)
    {
        if (target.y < pos.y)
            return Vector2.Angle(Vector2.right, target - pos) * -1.0f - 90;
        else
            return Vector2.Angle(Vector2.right, target - pos) - 90;
    }