Search Unity

What's the best way to rotate a Vector2 in Unity?

Discussion in 'Scripting' started by gustavopinent, Aug 17, 2019.

  1. gustavopinent

    gustavopinent

    Joined:
    Jan 14, 2019
    Posts:
    38
    I am dealing with several issues about Vectors, and I am a bit rusty in Mathematics. Sometimes I did implement some trigonometric solutions and find out later there was a static method to solve it quickly.

    This time, I need to rotate a Vector2 value in the z axis according with an angle. The process is this: https://en.wikipedia.org/wiki/Rotation_matrix. I looked for an answer in Unity C# and didn't find. Before starting to code these matrix operations, I would like to know if there is something ready in Unity, or at list some half way.

    Any ideas?
     
    neonblitzer likes this.
  2. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    I'm not sure about Vector2s but with Vector3 you can multiply with a quaternion to rotate the object.

    try something like (Quaternion.Euler(0f,0f, angle) * myVector2) maybe? I'm not sure what you mean by rotate a Vector2 on the Z axis.
     
    Semi_Rose likes this.
  3. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    As a rule of thumb, if it's something often done in games, then it's most likely done by the Unity API for you.
    However, my mathematics are also a bit rusty and i'm not entirely sure what it is you are trying to achieve. If you could give an actual example of what you want to do, then i'd say people will probably be faster to help.

    You may or may not look for something like this: https://docs.unity3d.com/ScriptReference/Quaternion.AngleAxis.html
    There are also functions like Transform.Rotate() or Transform.RotateAround(), and we even have a Matrix struct, which also features Rotate(). Somewhere in there will probably be what you need, i'm just not entirely sure what that is. Why do you want to rotate an Vector2 (containing x and y) around the z Axis? Kinda curious.
     
  4. gustavopinent

    gustavopinent

    Joined:
    Jan 14, 2019
    Posts:
    38
    I tried operations with Quaternion values, seemed logic to me, but generate errors as illegal operations, so I moved on. Maybe I was not doing right...

    That's what I am using to avoid the problem - creating a pivot to turn the end of the vector around the origin point:
    Code (CSharp):
    1. modulo = Instantiate(icoModulo);
    2.         modulo.name = "modulo";
    3.         modulo.tag = "mapElement";
    4.         pivoModulo = new GameObject("pivoModulo");
    5.         pivoModulo.tag = "mapElement";
    6.         modulo.transform.parent = pivoModulo.transform;
    Then I can turn the pivot...
    Code (CSharp):
    1. Vector2 pos = -1 * escala * area.transform.position;
    2.                 Vector3 modPos = new Vector3(pos.x, pos.y, Zpos["modulo"]);
    3.                 Quaternion modRot = Quaternion.Inverse(area.transform.rotation);
    4.                 modulo.transform.rotation = modRot;
    5.                 pivoModulo.transform.rotation = modRot;
    6.                 modulo.transform.localPosition = new Vector3(pos.x, pos.y, Zpos["modulo"]);
    This case is a ship flying in a 2D space called "area". This area will be translated and also rotated outside it's origin point. So it's tricky when I wish to show the position of the ship in a plane radar in x,y axis. I have to bring "area" to the same orientation as my radar ("escala" is the scale between "area" and my radar), I have to rotate it back.

    With the pivot I solved my problem, but though will be interesting and useful to have the mathematical solution for any other situation that maybe won't be possible to use a pivot, or maybe some more elegant and optimized solution for this kind of problems. So if you have a solution, please share.
     
  5. Boz0r

    Boz0r

    Joined:
    Feb 27, 2014
    Posts:
    419
    If I couldn't find a method to rotate a vector I'd probably just implement a rotation matrix in a helper function. Rotating a 2D vector is really simple:

    Code (CSharp):
    1. public static Vector2 rotate(Vector2 v, float delta) {
    2.     return new Vector2(
    3.         v.x * Mathf.Cos(delta) - v.y * Mathf.Sin(delta),
    4.         v.x * Mathf.Sin(delta) + v.y * Mathf.Cos(delta)
    5.     );
    6. }
    EDIT: That's in radians, btw. If you need degrees, multiply by Mathf.Deg2Rad or Mathf.Rad2Deg depending on direction.
     
  6. gononono64

    gononono64

    Joined:
    Mar 1, 2015
    Posts:
    13
    Damn you beat me to it.
    Although yours is better because i would have set it so that it only affected the object that the script was attached to making it less versatile

    MUHAHAHAHHAHAHAHA

    good post tho

    Since you already answer it with a solid answer let me instead be a giant dickus
    https://lmgtfy.com/?q=unity+rotate+vector2
     
    Last edited: Aug 20, 2019
  7. Boz0r

    Boz0r

    Joined:
    Feb 27, 2014
    Posts:
    419
    Yeah, I thought about doing that too, but I thought I'd try being nice for once in my life :p
     
  8. gustavopinent

    gustavopinent

    Joined:
    Jan 14, 2019
    Posts:
    38
    You both should pay attention to the title and the question before mocking with noobies. The point here is an advice of best practice. I just coded a cinematic algorithm that resulted in division by near zero value - classic problem. So I will test this sin - cos solution before actually use it, I might have to include exceptions, round numbers etc, things that was already done for sure. Wanna be nice? Just answer the question and share a bit of your experience (in coding, not mocking).
     
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
  10. Boz0r

    Boz0r

    Joined:
    Feb 27, 2014
    Posts:
    419
    I'm pretty sure that's exactly what I did in my first reply, though.
     
    neonblitzer likes this.
  11. mklasson

    mklasson

    Joined:
    Oct 30, 2018
    Posts:
    28
    neonblitzer and Bunny83 like this.
  12. EmpireStudios

    EmpireStudios

    Joined:
    Oct 23, 2018
    Posts:
    24
    Where do I put this in the code:

    Code (CSharp):
    1.     public float speed = 5;
    2.     Vector2 velocity;
    3.  
    4.  
    5.     void Update()
    6.     {
    7.         velocity.y = Input.GetAxis("Vertical") * speed * Time.deltaTime;
    8.         velocity.x = Input.GetAxis("Horizontal") * speed * Time.deltaTime;
    9.         transform.Translate(velocity.x, 0, velocity.y);
    10.     }
    11.  
    12.     public static Vector2 Rotate(Vector2 v, float delta)
    13.     {
    14.         return new Vector2(
    15.             v.x * Mathf.Cos(delta) - v.y * Mathf.Sin(delta),
    16.             v.x * Mathf.Sin(delta) + v.y * Mathf.Cos(delta)
    17.         );
    18.     }
     
    AAAAAAAAAE likes this.
  13. sketchygio

    sketchygio

    Joined:
    Nov 6, 2014
    Posts:
    31
    Funny part about this is that, a year later, this thread is the first thing that comes up from that google search! Super glad you answered that question helpfully and ty for really useful code!

    Had to google what that code meant though, since I like to try and understand the math as much as I can, rather than blind copy/pasting. For other code newbies such as myself trying to figure that code out, I found this helpful https://en.wikipedia.org/wiki/Rotation_matrix
     
    BaraShiro and Boz0r like this.
  14. SkitzFist

    SkitzFist

    Joined:
    Nov 10, 2016
    Posts:
    3
    I might be a bit late to the party but I've been using this:


    Vector2 rotateVector2(Vector2 vec, angle) {
    const float PI = 3.141592f;
    float dirAngle = Mathf.Atan2(vec.y, vec.x);
    dirAngle *= 180 / PI;
    float newAngle = (dirAngle + angle) * PI / 180;
    Vector2 newDir = new Vector2(Mathf.Cos(newAngle), Mathf.Sin(newAngle) );
    return newDir.normalized;
    }


    It might not be the most optimized code, but it works and rotates a vector by any degree you want.

    If you only need to rotate a vector to the right or left or 180 degree this is a much faster way:


    Vector2 rotateToLeft(Vector2 vec) {
    return new Vector2(vec.y * -1.0f, vec.x).normalized;
    }

    Vector2 rotateToRight(Vector2 vec) {
    return new Vector2(vec.y, vec.x * -1.0f).normalized;
    }

    Vector2 rotate180(Vector2 vec) {
    vec = new Vector2(vec.y, vec.x * -1);
    vec = new Vector2(vec.y, vec.x * -1);
    return vec;
    }


    What the code does is simply multiplying vector.x with -1 and then switching x with y.

    Vec[1,0]
    vec.x * -1
    vec[0,-1]

    that will rotate the vector to the right.
    If you multiply the Y with -1 instead it rotates to the left.

    All rotations are in 90 degrees.
     
  15. DSivtsov

    DSivtsov

    Joined:
    Feb 20, 2019
    Posts:
    151
    Wasn't the Previous variant can rotate on any angle?
    And the result vector initially will be normalized and radians can also be simple summarized, and Pi exist in library initially.
    Code (CSharp):
    1. Vector2 rotateVector2(Vector2 vec, float angle)
    2. {
    3.  float newAngle = Mathf.Atan2(vec.y, vec.x) + angle * Mathf.Deg2Rad;
    4.  return new Vector2(Mathf.Cos(newAngle), Mathf.Sin(newAngle));
    5. }
    The main difference between this and that variants, your variant returns a normalized Vector2, that variant returns the original Vector2 after rotation
     
    Last edited: Dec 4, 2021
    neonblitzer and hms0589 like this.
  16. unity_I5G15xBdXoH92g

    unity_I5G15xBdXoH92g

    Joined:
    Jun 8, 2022
    Posts:
    1
    Thanks man, this is just what I needed. I used this to change my movement vector2 to match the direction my charactor is looking so w always moves forward and a,d strafe.
     
  17. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,992
    Why haven't you issued a bug report on the github repository ^^. The bug is still there. I've just created an issue, explained the problem and even linked to your post.
     
    lordofduct likes this.
  18. mklasson

    mklasson

    Joined:
    Oct 30, 2018
    Posts:
    28
    Replying to the author here was a lot easier for me, but good on you :)
     
  19. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    Fixed it.

    Though note, I don't actually do work in the 3.0 version anymore. I've completely refactored the project in my 4.0 so that it follows the Unity 'packages' setup.
    https://github.com/lordofduct/spacepuppy-unity-framework-4.0

    The bug existed there too, and so I fixed it there as well.

    Thanks guys.
     
    SparrowGS and Bunny83 like this.