Search Unity

How do you rotate a direction vector?

Discussion in 'Scripting' started by Draconic, Jul 23, 2014.

  1. Draconic

    Draconic

    Joined:
    Oct 12, 2013
    Posts:
    82
    I have a raycast detection system for the player, mainly so I could rotate him (you can't rotate with the
    character controller). The raycasts form a square around the player from the center, but do not rotate with
    the player. For example, if the player z is 0 (the game is 2D), then the direction of the raycasts will be calculated by it size. So, up will be (0, 0.5, 0). However, I would like his rotation to affect the direction of the raycasts, so if his z is 180, then the raycast that was pointing upwards will be pointing downwards. Is there a way I can do this? I am sticking to direction vectors for the raycasts. I do not want to use transform.up and the like, because I need every possible direction around the player.
     
    Last edited: Jul 24, 2014
  2. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    What's wrong with transform.up and transform.right? You can take their negatives to get the equivalent to transform.down and transform.right.

    Code (csharp):
    1. /// Raycast to the object's left. Not necessarily the world's left.
    2. void bool RaycastLeft() {
    3.     Vector3 startPosition = transform.position;
    4.     // This is always the object's left. Does not always match Vector3.left.
    5.     Vector3 directionToRaycast = -transform.right;
    6.     return Physics.Raycast(startPosition, directionToRaycast);
    7. }
     
    Last edited: Jul 24, 2014
  3. Draconic

    Draconic

    Joined:
    Oct 12, 2013
    Posts:
    82

    How could I get something like 34.5 degrees? If transform.up would be 0 degrees, and -transform.up would be 180, is there any way to get in between?
     
  4. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    This is a common question. And yet I only know how to do it using trigonometry.
    1. Convert degrees to radians.
    2. Take the tangent.
    3. The new Vector2 is (transform.right + tangent * transform.up).normalized, if I remember my trig properly.
    4. May have to flip some signs depending on what quadrant your angle is.
    I've seen many people ask that question and it always inevitably needs trig functions, dot products, or cross products... Seems like there would be a simpler way of rotating vectors. Transforms get a Rotate() function, but not Vectors. >.>
     
    Last edited: Jul 24, 2014
  5. Draconic

    Draconic

    Joined:
    Oct 12, 2013
    Posts:
    82
    I hardly understand trig, I just started learning it. Could you please look at my code, and edit it a bit? To continue creating my game I need this to work, it is a one of the main mechanics to rotate the player. Help would be really appreciated!

    Code (csharp):
    1.  
    2. bool arRayRight(float scaleMin, float scaleMax, int increments){
    3.         float scale;
    4.         float a = box.transform.localScale.y / 2;
    5.         float b = box.transform.localScale.x / 2;
    6.         for(int i = 0; i < increments; i++){
    7.             scale = scaleMin + (scaleMax - scaleMin) / (increments - 1) * i;
    8.             Vector3 dir = new Vector3(b, scale / 2, 0);
    9.             float dist = Mathf.Sqrt((Mathf.Pow(scale / 2, 2) + Mathf.Pow (b, 2))); // Pythagoras
    10.             if(Physics.Raycast(box.transform.position, dir, dist)){
    11.                 return true;
    12.             }
    13.         }
    14.         return false;
    15.     }
    16.  
    I have a set of functions for detecting collisions on each side of the player. The player is a quad, 1 y and 0.5 x.
    "arRayRight" is one of 4 functions that make a set number of rays spanned across the corresponding side of the player, from the center of the player. This script is dependant from the transform, "box" is the object which controls the transform of the player. scaleMin and scaleMax are just modifiers for the affected area so sides don't overlap. Now what I want is the Vector3 dir to be rotating with box.transform.eulerAngles.z.

    Thanks for the previous answers aswell, help here would let me continue on my game!
     
  6. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    Okay, I think I understand what's going on here. We can change that Vector3 dir just a little bit and it'll align with the box's rotation.

    Code (csharp):
    1. Vector3 dir = b * box.transform.right + (scale / 2f) * box.transform.up;
    I separated the x and y component of dir, and treated transform.right as the new x axis and transform.up as the new y axis.
     
  7. Draconic

    Draconic

    Joined:
    Oct 12, 2013
    Posts:
    82
    Thank you so much :D I applied that to all 12 of the raycasting functions, and now my 2 week old "Gravity mode" which I scrapped is working again.

    Thanks again!
     
  8. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Quaternions are your friend. If you multiply a direction quaternion by a direction vector (order matters) the result is a new vector equivalent to the input vector rotated by the input quaternion. There's a function to generate a quaternion from euler angles, too.
     
    GarthSmith and StarManta like this.