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 float RADIUS = 10;
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()
{
//Generate move radius
if (Input.GetMouseButtonDown(0) && mesh == null)
{
//Re-enable move radius's Mesh Renderer
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
vertices.Add(Vector3.zero);
///*
//Populate line vertices
for (int i = 0; i < lines.Length; i++)
{
Vector3 direction = new Vector3(Mathf.Sin(Mathf.Deg2Rad * i), 0, Mathf.Cos(Mathf.Deg2Rad * 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)
{
triangles.Add(0);
triangles.Add(processedVertices + 1);
triangles.Add(processedVertices + lines[l].Length + 1);
}
//If there is no imbalance yet or really ever
else if (v < lines[l].Length && v < lines[l + 1].Length)
{
triangles.Add(processedVertices + v);
triangles.Add(processedVertices + v + 1);
triangles.Add(processedVertices + lines[l].Length + v);
triangles.Add(processedVertices + lines[l].Length + v);
triangles.Add(processedVertices + v + 1);
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);
triangles.Add(processedVertices + v);
triangles.Add(processedVertices + v + 1);
}
//If the imbalance favors the next line
else if (v < lines[l + 1].Length)
{
triangles.Add(processedVertices + lines[l].Length);
triangles.Add(processedVertices + lines[l].Length + v + 1);
triangles.Add(processedVertices + lines[l].Length + v);
}
}
processedVertices += lines[l].Length;
}
//*/
//Create Mesh
CreateMesh(vertices.ToArray(), triangles.ToArray());
}
}
//Functions
Vector3[] CreateVertexArray(Vector3 origin, Vector3 direction)
{
List<Vector3> returnValue = new List<Vector3>();
float distance = RADIUS;
RaycastHit hit;
bool endLine = false;
for (float angle = -THRESHOLD; angle <= THRESHOLD; angle++)
{
//Add in the Y dimension
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)
{
returnValue.Add(hit.point);
origin = hit.point - (direction * Mathf.Abs(GameObject.Find("Level").transform.position.y));
angle = -46;
distance -= hit.distance;
}
else if (hit.distance >= distance)
{
returnValue.Add(origin + (combinedVector * distance));
break;
}
}
else
{
returnValue.Add(origin + (combinedVector * distance));
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;
}
}