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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Rotate a vector

Discussion in 'Scripting' started by Arghonot, Jul 30, 2018.

  1. Arghonot

    Arghonot

    Joined:
    Dec 14, 2016
    Posts:
    4
    Hello everyones !

    I am currently trying to place 4 spheres on an object using raycast.
    I want my 4 rays to form something like a camera frustrum. so I have my "ray caster object"'s direction as frustrum center, a max distance for my ray and X/Y axises as follow :
    • -x ; y
    • x ; y
    • x ; -y
    • -x ; -y
    my code so far :

    Code (CSharp):
    1.     public Vector2 Angles;
    2.     public float MaxDistance;
    3.  
    4.     public Material mat;
    5.  
    6.     List<GameObject> Spheres;
    7.  
    8.  
    9.     void Start ()
    10.     {
    11.         Spheres = new List<GameObject>();
    12.  
    13.         // I create all my spheres
    14.         for (int i = 0; i < 4; i++)
    15.         {
    16.             Spheres.Add(GameObject.CreatePrimitive(PrimitiveType.Sphere));
    17.             Spheres.Last().GetComponent<SphereCollider>().enabled = false;
    18.             Spheres.Last().GetComponent<MeshRenderer>().material = mat;
    19.             Spheres.Last().transform.localScale = Vector3.one * 0.1f;
    20.         }
    21.     }
    22.  
    23.     void Update ()
    24.     {
    25.         // I set the position of all my spheres
    26.         // in order to simulate a camera's frustrum (so one at each corner)
    27.         SetSphere(0, -1, 1);
    28.         SetSphere(1, 1, 1);
    29.         SetSphere(2, 1, -1);
    30.         SetSphere(3, -1, -1);
    31.  
    32.     }
    33.     void SetSphere(int index, float signX, float signY)
    34.     {
    35.         // I get the direction my raycast will follow
    36.         Vector3 direction = Quaternion.Euler(Angles.x * signX, Angles.y * signY, 1f) * transform.forward;
    37.         Vector3 position = GetImpactPoint(direction);
    38.  
    39.         Spheres[index].transform.localPosition = position;
    40.  
    41.         // If we hit nothing
    42.         if (Spheres[index].transform.position == Vector3.zero)
    43.         {
    44.             Spheres[index].transform.localPosition = direction * MaxDistance;
    45.         }
    46.  
    47.     }
    48.  
    49.     Vector3 GetImpactPoint(Vector3 direction)
    50.     {
    51.         Ray ray = new Ray(transform.position, direction);
    52.         RaycastHit hitinfo = new RaycastHit();
    53.  
    54.         if (Physics.Raycast(ray, out hitinfo, MaxDistance))
    55.         {
    56.             // We will set the sphere's local position as the intersection point
    57.             return hitinfo.point;
    58.         }
    59.         return Vector3.zero;
    60.     }
    How it work :
    spheres ok.PNG

    My problem :
    spheres no.PNG

    The code works pretty well for X and Y translation / rotation on the object that cast the rays, but I would like to make z rotation affect the rays (second picture). I thought multiplying the direction by the transform.forward at line 36 would do the trick but it doesn't.
    I already tried adding empties gameobject in order to work with the local / world frames, vector3 and quaternion functions, using transform.up at line 36 instead of forward or using trigonometry to add the z axis rotation to my direction but none of my attempts worked so far.

    Does anybody have an idea ?

    Help me developpers, you are my only hope ! :rolleyes:
     
  2. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    The frustrum is strong with this one! :D
     
  3. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    I haven't looked at your code but just wondering, can you not parent the spheres to the pivot point (not sure if that represents your camera or not) after you place them? Then if the pivot rotates about the Z axis, the spheres will move in harmony with it. Would that work for you?
     
  4. Arghonot

    Arghonot

    Joined:
    Dec 14, 2016
    Posts:
    4
    Yes indeed ! :cool:

    Thanks for your quick response btw !
    So I tried and I also set the red spheres localposition instead of position (in order to make it work) and the problem is that if I do that, rotations are okay but position aren't anymore as they are set from the parent's position. So now they appear flotting in front of the white sphere :/
     
  5. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    Ok, so what about creating a new empty GameObject that sits at the central point of the 4 red spheres (called, say, pivotReds). Parent the reds to pivotReds instead of the camera (is that what it is in your image?). And then when the camera rotates, make pivotReds rotate in sympathy.

    Then the camera can move and the reds will remain fixed in place but will rotate accordingly.
     
  6. Arghonot

    Arghonot

    Joined:
    Dec 14, 2016
    Posts:
    4
    I guess the timing was bad :/ I found another solution at the same time you replied. I will post it for everybody :

    I am using the transform's rotation of the red spheres to do the hard work. At start I set them as son of the gameobject containing the script . I also set their rotation as the angle I want in order to have my "cone shape" between the 4 spheres and their parent (I could do it every frame in order to update the angle but whatever).

    Code (CSharp):
    1.  
    2.     public Vector2 Angles;
    3.     public float MaxDistance;
    4.  
    5.     public Material mat;
    6.  
    7.     List<GameObject> Spheres;
    8.  
    9.     private void Start()
    10.     {
    11.         Spheres = new List<GameObject>();
    12.  
    13.         // I create all my spheres
    14.         for (int i = 0; i < 4; i++)
    15.         {
    16.             Spheres.Add(GameObject.CreatePrimitive(PrimitiveType.Sphere));
    17.             Spheres.Last().GetComponent<SphereCollider>().enabled = false;
    18.             Spheres.Last().GetComponent<MeshRenderer>().material = mat;
    19.             Spheres.Last().transform.localScale = Vector3.one * 0.1f;
    20.             Spheres.Last().transform.parent = transform;
    21.         }
    22.  
    23.         // I set their orientation
    24.         Spheres[0].transform.localRotation = Quaternion.Euler(Angles.x * -1f, Angles.y * 1f, 0f);
    25.         Spheres[1].transform.localRotation = Quaternion.Euler(Angles.x * 1f, Angles.y * 1f, 0f);
    26.         Spheres[2].transform.localRotation = Quaternion.Euler(Angles.x * 1f, Angles.y * -1f, 0f);
    27.         Spheres[3].transform.localRotation = Quaternion.Euler(Angles.x * -1f, Angles.y * -1f, 0f);
    28.     }
    29.  
    30.     private void Update()
    31.     {
    32.         for (int i = 0; i < Spheres.Count; i++)
    33.         {
    34.             // Their world position = the impact position
    35.             Spheres[i].transform.position = SetImpactPosition(i);
    36.         }
    37.     }
    38.  
    39.     Vector3 SetImpactPosition(int index)
    40.     {
    41.         Ray ray = new Ray(transform.position, Spheres[index].transform.forward);
    42.         RaycastHit HitInfo = new RaycastHit();
    43.  
    44.         if (Physics.Raycast(ray, out HitInfo, MaxDistance))
    45.         {
    46.             return HitInfo.point;
    47.         }
    48.  
    49.         // If no collision, we take our position and add the direction of our red sphere * the distance we look for collision
    50.         return transform.position + (Spheres[index].transform.forward * MaxDistance);
    51.     }
    I want to thank you very much for your time and your idea to use gameobject as pivot ! :)
     
    Doug_B likes this.
  7. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    Good stuff, glad you got a working solution. :)