'Finding the closest vertex below a certain height, from a start position

I have procedurally generated Islands with lakes, its basically a 3D mesh that has points above the water line and points below it, any vertex/point below the water level is water, everything above it is solid ground.

From any point on the mesh I want to know the closest distance to this water.

What I ended up doing was creating an Array of Vector2s, the array contains all the points on the mesh that are below the water level.

Next I wish to cycle through these elements and compare them all to find the closest one to my selected point. I am using Vector2.Distance for this because I only want the distance in the XZ components and not going up/down (Y Component).

The problem is that for most points I select this works absolutely fine, giving correct results, but sometimes it doesn't take the closest water point but instead one that is further away, even though this closer water point is confirmed to be in the array of water points that are being compared to find the closest one.

here is my code:

chunk.Vertices = new Vertice[totalVertices];
    for (int i = 0, z = 0; z <= chunkSizeZ; z++)
    {
        for (int x = 0; x <= chunkSizeX; x++, i++)
        {

            Vertice vert = new Vertice();
            vert.index = i;

            vert.position = new Vector3(chunkStartPosition.x + x,
                                        chunkStartPosition.y,
                                        chunkStartPosition.z + z);

            vert.centerPosition = new Vector3(vert.position.x + 0.5f,
                                              vert.position.y,
                                              vert.position.z + 0.5f);

            vert.centerPos2 = new Vector2(vert.position.x + 0.5f,
                                          vert.position.z + 0.5f);

            chunk.Vertices[i] = vert;
        }
    }

Here we get all the water positions:

    for (int i = 0; i < totalVertices; i++)
    {
        if (chunk.Vertices[i].position.y > heightCorrection + tileColliderMinimumY)
        {
            worldVectorsClean.Add(chunk.Vertices[i].position);
            worldIndexClean.Add(chunk.Vertices[i].index);
        }
        else
        {
            worldVectorsWater.Add(chunk.Vertices[i].centerPos2);
        }
    }

Every single tile then calls this function on the generator itself, but only AFTER the whole map and all water points are added. Because the generator keeps track of ALL waterpoints across all chunks otherwise each chunk will only compare its own waterpoints which doesn't work because water from another chunk can be closer but wont be compared to if we don't do it this way;

public float CalculateDistanceToWater(Vector2 pos)
{
    var distance = 9001f;
    foreach (Vector2 waterVector in worldVectorsWater)
    {
        var thisDistance = Vector2.Distance(pos, waterVector);
        if (thisDistance < distance)
            distance = thisDistance;
    }
    return distance;
}

Finally when we call it from

 IEnumerator FindWater()
{
    yield return new WaitForSeconds(Random.Range(0.8f, 2.55f));

    var pos = new Vector2(transform.position.x, transform.position.z);
    distanceToWater = ChunkGenerator.instance.CalculateDistanceToWater(pos);
}

Looking forward to some help on this.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source