Search Unity

Resolved Werid problem with Raycasting

Discussion in 'Scripting' started by Zero_Xue, Mar 19, 2023.

  1. Zero_Xue

    Zero_Xue

    Joined:
    Apr 18, 2012
    Posts:
    126
    Ive run into a very weird problem when raycasting, when my object has no rotation everything is ok and all the point connect correctly as expected -
    A.png

    However as soon as i rotate the object nothing connects....

    B.png

    this is the code for my raycasts, when checking the SqrMagitude changes on the rotated object and i have no idea how to fix...

    Code (CSharp):
    1.                 RaycastHit[] Hits = Physics.RaycastAll(Pos + new Vector3(0, 500, 0), -Vector3.up, 1000);
    2.                 Hits = Hits.OrderBy(item => item.point.y).ToArray();
     
  2. samana1407

    samana1407

    Joined:
    Aug 23, 2015
    Posts:
    244
    To be honest, it is absolutely unclear what is going on in the picture and what the shown code has to do with it.
     
    Bunny83 likes this.
  3. Zero_Xue

    Zero_Xue

    Joined:
    Apr 18, 2012
    Posts:
    126
    Yea sorry, am making grid all nodes are spaced equally and placed in dictionary with the Vector3 Position as its key, then connected up by lookup

    Code (CSharp):
    1.             Vector3 NP = new Vector3(Node.Position.x, Node.Position.y, Node.Position.z);
    2.             Vector3 Additional = new Vector3(1, 0, 0);
    3.             if (Nodes.ContainsKey(NP + Additional))
    4.             {
    5.                 Node.Neighbours.Add(Nodes[NP + Additional]);
    6.             }
    so on and so forth, it all works perfectly fine if the object that being raycast isnt rotated but as soon as it is even though the node positions havent changed it wont connect the nodes up.
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,930
    Use Debug.DrawRay/DrawLine to debug where the raycasts are going. That will probably lead you to what's going wrong.

    Only saying this as it's still really hard to tell what's going with the tiny snippets of our of context code.
     
  5. Zero_Xue

    Zero_Xue

    Joined:
    Apr 18, 2012
    Posts:
    126
    Should point out the game object casting the rays is not the same object being hit

    Code (CSharp):
    1.     void CreateGrid()
    2.     {
    3.         for (int x = -(GridSize / 2); x < (GridSize / 2); x++)
    4.         {
    5.             for (int z = -(GridSize / 2); z < (GridSize / 2); z++)
    6.             {
    7.                 Vector3 Pos = new Vector3(x, 0, z);
    8.                 RaycastHit[] Hits = Physics.RaycastAll(Pos + new Vector3(0, 500, 0), -Vector3.up, 1000);
    9.                 //Hits = Hits.OrderBy(item => item.point.y).ToArray();
    10.                 for (int i = 0; i < Hits.Length; i++)
    11.                 {
    12.                     float hx = Hits[i].point.x;
    13.                     float hy = Mathf.Round(Hits[i].point.y * 10) / 10;
    14.                     float hz = Hits[i].point.z;
    15.  
    16.                     Vector3 HitPos = new Vector3(hx,hy,hz);
    17.                
    18.                     //if (Physics.SphereCastAll(HitPos, EdgeDetection, Vector3.up, EdgeDetection).Length != 1)
    19.                     //{
    20.                     //    continue;
    21.                     //}
    22.  
    23.                     if (Hits.Length == 1)
    24.                     {
    25.                         Nodes.Add(HitPos, new PF_Node(HitPos));
    26.                     }
    27.                     else
    28.                     {
    29.                         try
    30.                         {
    31.                             if ((Mathf.Round(Hits[i + 1].point.y * 10) / 10) - HitPos.y >= ImpassThreshold)
    32.                             {
    33.                                 Nodes.Add(HitPos, new PF_Node(HitPos));
    34.                             }
    35.                         }
    36.                         catch (System.Exception)
    37.                         {
    38.                             //Assume Nothing above it.
    39.                             Nodes.Add(HitPos, new PF_Node(HitPos));
    40.                         }
    41.                     }
    42.                 }
    43.             }
    44.         }
    45.  
    46.  
    47.         foreach (var Node in Nodes.Values)
    48.         {
    49.             Vector3 NP = new Vector3(Node.Position.x, Node.Position.y, Node.Position.z);
    50.             Vector3 Additional = new Vector3(1, 0, 0);
    51.             if (Nodes.ContainsKey(NP + Additional))
    52.             {
    53.                 Node.Neighbours.Add(Nodes[NP + Additional]);
    54.             }
    55.             Additional = new Vector3(-1, 0, 0);
    56.             if (Nodes.ContainsKey(NP + Additional))
    57.             {
    58.                 Node.Neighbours.Add(Nodes[NP + Additional]);
    59.             }
    60.             Additional = new Vector3(0, 0, 1);
    61.             if (Nodes.ContainsKey(NP + Additional))
    62.             {
    63.                 Node.Neighbours.Add(Nodes[NP + Additional]);
    64.             }
    65.             Additional = new Vector3(0, 0, -1);
    66.             if (Nodes.ContainsKey(NP + Additional))
    67.             {
    68.                 Node.Neighbours.Add(Nodes[NP + Additional]);
    69.             }
    70.  
    71.             Additional = new Vector3(-1, 0, 1);
    72.             if (Nodes.ContainsKey(NP + Additional))
    73.             {
    74.                 Node.Neighbours.Add(Nodes[NP + Additional]);
    75.             }
    76.             Additional = new Vector3(-1, 0, -1);
    77.             if (Nodes.ContainsKey(NP + Additional))
    78.             {
    79.                 Node.Neighbours.Add(Nodes[NP + Additional]);
    80.             }
    81.             Additional = new Vector3(1, 0, 1);
    82.             if (Nodes.ContainsKey(NP + Additional))
    83.             {
    84.                 Node.Neighbours.Add(Nodes[NP + Additional]);
    85.             }
    86.             Additional = new Vector3(1, 0, -1);
    87.             if (Nodes.ContainsKey(NP + Additional))
    88.             {
    89.                 Node.Neighbours.Add(Nodes[NP + Additional]);
    90.             }
    91.  
    92.             float MaxHeightDist = GetMaxAngleHeight();
    93.             for (float i = -MaxHeightDist; i < MaxHeightDist; i+=0.1f)
    94.             {
    95.                 i = Mathf.Round(i * 10) / 10;
    96.            
    97.                 Additional = new Vector3(1, i, 0);
    98.                 if (Nodes.ContainsKey(NP + Additional))
    99.                 {
    100.                     Node.Neighbours.Add(Nodes[NP + Additional]);
    101.                 }
    102.                 Additional = new Vector3(-1, i, 0);
    103.                 if (Nodes.ContainsKey(NP + Additional))
    104.                 {
    105.                     Node.Neighbours.Add(Nodes[NP + Additional]);
    106.                 }
    107.                 Additional = new Vector3(0, i, 1);
    108.                 if (Nodes.ContainsKey(NP + Additional))
    109.                 {
    110.                     Node.Neighbours.Add(Nodes[NP + Additional]);
    111.                 }
    112.                 Additional = new Vector3(0, i, -1);
    113.                 if (Nodes.ContainsKey(NP + Additional))
    114.                 {
    115.                     Node.Neighbours.Add(Nodes[NP + Additional]);
    116.                 }
    117.  
    118.                 Additional = new Vector3(-1, i, 1);
    119.                 if (Nodes.ContainsKey(NP + Additional))
    120.                 {
    121.                     Node.Neighbours.Add(Nodes[NP + Additional]);
    122.                 }
    123.                 Additional = new Vector3(-1, i, -1);
    124.                 if (Nodes.ContainsKey(NP + Additional))
    125.                 {
    126.                     Node.Neighbours.Add(Nodes[NP + Additional]);
    127.                 }
    128.                 Additional = new Vector3(1, i, 1);
    129.                 if (Nodes.ContainsKey(NP + Additional))
    130.                 {
    131.                     Node.Neighbours.Add(Nodes[NP + Additional]);
    132.                 }
    133.                 Additional = new Vector3(1, i, -1);
    134.                 if (Nodes.ContainsKey(NP + Additional))
    135.                 {
    136.                     Node.Neighbours.Add(Nodes[NP + Additional]);
    137.                 }
    138.             }
    139.         }
    140.     }
    Also doing some breakpoint checks seems to show an inexpected result..

    NP + Additional (While object is rotated -10 on Y)
    "(0.00, 0.50, -2.00)"
    magnitude: 2.061553
    normalized: "(0.00, 0.24, -0.97)"
    sqrMagnitude: 4.250002
    x: -2.384186E-07
    y: 0.5
    z: -2

    NP + Additional (While object is not rotated)
    "(0.00, 0.50, -2.00)"
    magnitude: 2.061553
    normalized: "(0.00, 0.24, -0.97)"
    sqrMagnitude: 4.25
    x: 0
    y: 0.5
    z: -2

    The sqrMagnitude and x pos are different - even though the positions are exactly the same
     
    Last edited: Mar 19, 2023
  6. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    Not really. The differences are microscopic. Not enough to worry about.
     
  7. Zero_Xue

    Zero_Xue

    Joined:
    Apr 18, 2012
    Posts:
    126
    Fixed it, Not sure why or how changing the hx,hy,hz to the below fixed it, at a guess it was a floating point issue.

    Code (CSharp):
    1.                     float hx = Mathf.Round((Hits[i].point.x * 10) / 10);
    2.                     float hy = Mathf.Round(Hits[i].point.y * 10) / 10;
    3.                     float hz = Mathf.Round((Hits[i].point.z * 10) / 10);
     
  8. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    I spotted the floating point issue as soon as you said...
    The rule of thumb in programming is to never depend on floating point equality when evaluating conditions. And that's exactly what happens in your Dictionary when you look something up by a Vector3 key - it has to check if a bunch of stored floats match a bunch of input floats.

    Basically, the issue with this approach is that (5 * 2) is not guaranteed to come up with the same floating point representation of the answer as (2.5 * 4) or (10 * 1) or (11 * (10/11)) or whatever. And that's not even getting into madness such as (3.333... * 3.333...). Your current calculation happens to end up with answers which have a matching floating point representation in current use cases, but there's no way I'd trust that to hold true generally.

    Personally, depending on what you're trying to do overall, I'd do one of the following:
    - Use Vector3Int as my key.
    - If this is a grid which is always fully populated, use a 3-dimensional array.
    Either way, I'd also have a function which takes a Vector3 position and returns a Vector3Int index, or equivalent.
     
    spiney199 likes this.
  9. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    Ew. I did'nt catch that! angrypenguin is right. Using floats as a dictionary key is a ruinously bad idea and will never work reliably (as you've already discovered).:eek:
     
    Last edited: Mar 21, 2023