Skip to content

Instantly share code, notes, and snippets.

@mattvr
Last active June 5, 2026 09:34
Show Gist options
  • Select an option

  • Save mattvr/8cdcc922d1a75d0a7a7abf5d46e23ef0 to your computer and use it in GitHub Desktop.

Select an option

Save mattvr/8cdcc922d1a75d0a7a7abf5d46e23ef0 to your computer and use it in GitHub Desktop.
Curved plane for Unity
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class CurvedPlane : MonoBehaviour
{
private class MeshData
{
public Vector3[] Vertices { get; set; }
public Vector2[] Uvs { get; set; }
public int[] Triangles { get; set; }
}
[SerializeField] private float height = 1f;
[SerializeField] private float radius = 2f;
[SerializeField] [Range(1, 1024)] private int numSegments = 32;
[SerializeField] [Range(0f, 360f)] private float curvatureDegrees = 60f;
[SerializeField] private bool useArc = true;
[SerializeField] private bool flipNormals = false;
private MeshData plane;
void Start()
{
Generate();
}
void OnValidate()
{
Generate();
}
[ContextMenu("Generate")]
public void Generate()
{
GenerateScreen();
UpdateMeshFilter();
}
private void UpdateMeshFilter()
{
var filter = GetComponent<MeshFilter>();
var mesh = new Mesh
{
vertices = plane.Vertices,
uv = plane.Uvs,
triangles = plane.Triangles
};
mesh.RecalculateNormals();
mesh.RecalculateBounds();
filter.mesh = mesh;
}
private void GenerateScreen()
{
plane = new MeshData
{
Vertices = new Vector3[(numSegments + 2) * 2],
Uvs = new Vector2[(numSegments + 2) * 2],
Triangles = new int[numSegments * 6]
};
int i, j;
for (i = j = 0; i < numSegments + 1; i++)
{
GenerateVertexPair(ref i, ref j);
if (i < numSegments)
{
GenerateLeftTriangle(ref i, ref j);
GenerateRightTriangle(ref i, ref j);
}
}
}
private void GenerateVertexPair(ref int i, ref int j)
{
float amt = ((float)i) / numSegments;
float arcDegrees = curvatureDegrees * Mathf.Deg2Rad;
float theta = -0.5f + amt;
var x = useArc ? Mathf.Sin(theta * arcDegrees) * radius : (-0.5f * radius) + (amt * radius);
var z = Mathf.Cos(theta * arcDegrees) * radius;
plane.Vertices[i] = new Vector3(x, height / 2f, z);
plane.Vertices[i + numSegments + 1] = new Vector3(x, -height / 2f, z);
plane.Uvs[i] = new Vector2(amt, 1f);
plane.Uvs[i + numSegments + 1] = new Vector2(amt, 0f);
}
private void GenerateLeftTriangle(ref int i, ref int j)
{
plane.Triangles[j++] = i;
plane.Triangles[j++] = flipNormals ? i + numSegments + 1 : i + 1;
plane.Triangles[j++] = flipNormals ? i + 1 : i + numSegments + 1;
}
private void GenerateRightTriangle(ref int i, ref int j)
{
plane.Triangles[j++] = i + 1;
plane.Triangles[j++] = flipNormals ? i + numSegments + 1 : i + numSegments + 2;
plane.Triangles[j++] = flipNormals ? i + numSegments + 2 : i + numSegments + 1;
}
}
@BenHarksdorf

Copy link
Copy Markdown

I would suggest adding UVs to it.
You would just need to ad a uv array in the Mesh Data Set class, fill it like this after you set the vertices:

plane.UVs[i] = new Vector2(i / (float)numSegments, 1);
plane.UVs[i + numSegments + 1] = new Vector2(i / (float)numSegments, 0);

and then attach it to the mesh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment