# Is there something wrong with terrain colliders?

I recently wrote a script that generates a move radius out of a mesh surrounding my character and wanted to modify it to make the move radius climb up and down terrain given a certain angle threshold. After lots of painstaking effort I came up with something that MOSTLY works, but for whatever reason I still get little bits and pieces that clip through the terrain and I don’t know why.

This is what it looks like when the terrain is active:

And this is what it looks like when the terrain is turned off:

In case the problem is something super obvious this is the code I’m using to generate the move radius

``````public class UnitScript : MonoBehaviour
{
const int ANGLE = 361;
const float THRESHOLD = 45;
Mesh mesh;
public GameObject dot; //Ignore this. This is just a debugging tool to find the points of one of the lines

void OnMouseDown()
{
if (Input.GetMouseButtonDown(0) && mesh == null)
{
transform.GetChild(0).GetComponent<MeshRenderer>().enabled = true;

//Declare vertices and triangles for the mesh
Vector3[][] lines = new Vector3[ANGLE][];
List<Vector3> vertices = new List<Vector3>();
List<int> triangles = new List<int>();

//Origin

///*
//Populate line vertices
for (int i = 0; i < lines.Length; i++)
{
lines[i] = CreateVertexArray(transform.position + Vector3.down, direction);
}

//Add line vertices to the master list and plot the points
for (int y = 0; y < ANGLE; y++)
{
for (int x = 0; x < lines[y].Length; x++)
{
vertices.Add(lines[y][x] - (transform.position + (Vector3.down * transform.position.y)));
}
}

//Create triangles
int processedVertices = 0;

for (int l = 0; l < ANGLE - 1; l++)
{
for (int v = 0; v < Mathf.Max(lines[l].Length, lines[l + 1].Length); v++)
{
//First triangle
if (v == 0)
{
}

//If there is no imbalance yet or really ever
else if (v < lines[l].Length && v < lines[l + 1].Length)
{

triangles.Add(processedVertices + lines[l].Length + v + 1);
}

//If the imbalance favors the main line
else if (v < lines[l].Length)
{
triangles.Add(processedVertices + lines[l].Length + lines[l + 1].Length);
}

//If the imbalance favors the next line
else if (v < lines[l + 1].Length)
{
triangles.Add(processedVertices + lines[l].Length + v + 1);
}
}

processedVertices += lines[l].Length;
}
//*/

//Create Mesh
CreateMesh(vertices.ToArray(), triangles.ToArray());
}
}
//Functions
Vector3[] CreateVertexArray(Vector3 origin, Vector3 direction)
{
List<Vector3> returnValue = new List<Vector3>();
RaycastHit hit;
bool endLine = false;

for (float angle = -THRESHOLD; angle <= THRESHOLD; angle++)
{
Vector3 combinedVector = direction + new Vector3(0, Mathf.Sin(Mathf.Deg2Rad * angle), 0);

//Raycast the combined vector
if (Physics.Raycast(origin, combinedVector, out hit))
{
if (hit.distance < distance && hit.distance > 0.1f)
{
origin = hit.point - (direction * Mathf.Abs(GameObject.Find("Level").transform.position.y));
angle = -46;
distance -= hit.distance;
}
else if (hit.distance >= distance)
{
break;
}
}
else
{
break;
}

//Break if the distance is maxed out
if (endLine == true)
{
break;
}
}

return returnValue.ToArray();
}
void CreateMesh(Vector3[] vertices, int[] triangles)
{
mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
transform.GetChild(0).GetComponent<MeshFilter>().mesh = mesh;
}
}
``````

Terrain is not always rendered with a constant number of polygons. It has dynamic level-of-detail adjustment based on distance from camera. This means that high frequency features get smoothed at higher farther distances.

To see this for yourself, make a terrain with very detailed up/down noise on it, then put a Unity plane “in” the terrain so some of it clips through. Obviously make the plane different enough in color to see, then pull the camera back.

Ok, then how do I fix that?

You may be able to use multiple cameras and layers so that you know the blue circle is always drawn after the terrain.

Main camera sees terrain, second camera (clear flags to “clear depth only”) sees your circle, and if anyone else goes on top, have another camera for them.

Or you can probably do it with a custom shader that ignores Z depth, depending on how you’re doing stuff.

Ok, I have a second camera that moves along with the first and it has its clear flags set to depth only and nothing has changed. Now what?

Likewise I’m not sure if this is going to work anyway since I need the mesh collider to be clickable and I’m pretty sure that’s not going to happen if there’s still terrain in the way.