Search Unity

Get terrain height including objects

Discussion in 'Physics' started by stumpytheangry, Jan 12, 2022.

  1. stumpytheangry

    stumpytheangry

    Joined:
    Jan 13, 2021
    Posts:
    8
    I have a terrain which houses thousands of units. Each of these units needs to know the height of the terrain it's currently above.

    If it were 'just' terrain I could use something like

    Code (CSharp):
    1.     float newHeight = Terrain.activeTerrain.SampleHeight(transform.position);
    As it is I need to include some objects (buildings and tiles etc) which will (if present) override the SampleHeight.

    I have a solution for this using a raycast however I find that (because of the raycast) it is too slow for the game. Current (correct but slow) code is this (using a mask for either terrain or buildings):

    Code (CSharp):
    1.     public static Vector3 getHeightPosition(Vector3 point)
    2.     {
    3.        point.y = 100;
    4.        RaycastHit downHit;
    5.        if (Physics.Raycast(point, Vector3.down, out downHit, 110f, LayerMask.GetMask("terrain", "buildings"), QueryTriggerInteraction.Ignore))
    6.        {
    7.            return downHit.point;
    8.        }
    9.  
    10.        return new Vector3(point.x, 0, point.z);
    11.     }
    Given that in my map buildings are completely static I feel a better solution would be to somehow 'prebake' a new heightmap using a combination of terrain data and building objects which could be accessed without the slow raycast (similar to the sampleHeight solution) but I'm not aware how.

    Suggestions welcome - speed is the key here due to the number of active units.
     
  2. AlTheSlacker

    AlTheSlacker

    Joined:
    Jun 12, 2017
    Posts:
    326
    You don't say how precise this needs to be, so I'm going to assume it is something like air units flying over a static map and you just need to not fly through buildings / terrain...

    If that assumption is true, then I don't see why you cannot just have a 2D array of maximum heights for cells of an overlaid grid. Set a grid frequency as course as you can tolerate and enter the highest point in that cell, then you just look up the location of your units in that array when you want a ground height. Try it out on a small sample and see how it performs: If you like it then you can write some editor code to use your existing raycast approach to automatically construct a larger array for a larger map area.
     
    Last edited: Jan 12, 2022
  3. stumpytheangry

    stumpytheangry

    Joined:
    Jan 13, 2021
    Posts:
    8
    Thank you - I should have been clearer. I need this to be very precise as this is the mechanism that determines where all the units will be placed vertically - I'm not using physx+gravity so I need a coded mechanism.
     
  4. AlTheSlacker

    AlTheSlacker

    Joined:
    Jun 12, 2017
    Posts:
    326
    What are the dimensions of the placement area and what resolution of height map do you need?