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. Dismiss Notice

[SOLVED] C# | Unity | Check if Terrain is flat enough

Discussion in 'Scripting' started by _Luki_2001, Aug 23, 2016.

  1. _Luki_2001

    _Luki_2001

    Joined:
    Mar 22, 2015
    Posts:
    5
    Hey Guys,
    i wrote a method to check if a terrain is flat enough to place a building on it. The building should have an empty child called testPoints. The testPoints object also has 5 empty objects(one for each corner and one in the middle). Now I loop through all children of testPoints and raycast down. In the end I compare the highest RaycastHit and the lowest RaycastHit to see if the difference is acceptable.

    Error:
    The function always returns True. With the debugger I found out that the names of the Points change but the position always stays the same and the RaycastHit object is null the whole time. I also just see one Raycast, but they should be spread.

    Check() method:
    Code (CSharp):
    1. using UnityEngine;
    2.     public bool Check ()
    3.     {
    4.         float max = 0F;
    5.         float min = 0F;
    6.         RaycastHit hitInfo;
    7.         foreach (Transform point in testPoints.transform) {
    8.             Physics.Raycast (point.position, Vector3.down, out hitInfo, Mathf.Infinity, LayerMask.NameToLayer ("SolidGround"));
    9.             Debug.DrawRay (point.position, new Vector3 (0, -10, 0), Color.red);
    10.             if (hitInfo.point.y > max) {
    11.                 max = hitInfo.point.y;
    12.             } else if (hitInfo.point.y < min) {
    13.                 min = hitInfo.point.y;
    14.             }
    15.         }
    16.         return (max - min) < maxDifference;
    17.     }
    18.  
    Sorry for bad English and
    Thanks in advance!
     
    Last edited: Aug 23, 2016
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    nothing wrong on that front, nice first post :D

    usually with 3d raycasts they're couched in an if so
    Code (csharp):
    1.  
    2. if(Physics.Raycast(point.position, Vector3.down, out hitInfo, Mathf.Infinity, LayerMask.NameToLayer("SolidGround")))
    3. {
    4. // hitInfo isn't going to be null in here
    5. }
    6.  
    first thought would be to check the layer on the terrain is set correctly...

    this sounds very odd, I can't see anything wrong with the syntax, so assuming there are children it should iterate over them, what debug code did you use?
     
    _Luki_2001 likes this.
  3. _Luki_2001

    _Luki_2001

    Joined:
    Mar 22, 2015
    Posts:
    5
    Thanks for the quick reply!

    I fixed the problem with the same position(turns out I just spawned them and didn't move them to the corners :D).
    The terrain is on the right layer, I also added an if statement but it seems like the raycast isn't hitting anything.
    Here's the new code:
    Code (CSharp):
    1. public bool Check ()
    2.     {
    3.         float max = 0F;
    4.         float min = 0F;
    5.         RaycastHit hitInfo;
    6.         foreach (Transform point in testPoints.transform) {
    7.             Debug.DrawRay (point.position, new Vector3 (0, -10, 0), Color.red);
    8.             if (Physics.Raycast (point.position, Vector3.down, out hitInfo, Mathf.Infinity, LayerMask.NameToLayer ("SolidGround"))) {
    9.                 if (hitInfo.point.y > max) {
    10.                     max = hitInfo.point.y;
    11.                 } else if (hitInfo.point.y < min) {
    12.                     min = hitInfo.point.y;
    13.                 }
    14.             }
    15.         }
    16.         return (max - min) < maxDifference;
    17.     }
     
  4. _Luki_2001

    _Luki_2001

    Joined:
    Mar 22, 2015
    Posts:
    5
    Ok, got it working now, I changed 'LayerMask.NameToLayer' to 'LayerMask.GetMask' at line 8.
     
    LeftyRighty likes this.