Created
November 10, 2012 19:44
-
-
Save michaelbartnett/4052250 to your computer and use it in GitHub Desktop.
Generate flat terrain meshes in Unity by hand
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using IEnumerator=System.Collections.IEnumerator; | |
[RequireComponent(typeof(MeshRenderer))] | |
[RequireComponent(typeof(MeshFilter))] | |
[ExecuteInEditMode] | |
public class DrawTerrain : MonoBehaviour | |
{ | |
public int rows = 3; | |
public int columns = 3; | |
public Vector2 uvScale = Vector2.one; | |
public float vertVisitSpeed = 2; | |
private MeshFilter meshFilter; | |
private Mesh mesh; | |
public Vector3[] Vertices; | |
public Vector2[] UVs; | |
public int[] Indices; | |
public bool VisitingVertices { get; private set; } | |
void Awake() | |
{ | |
meshFilter = GetComponent<MeshFilter>(); | |
mesh = new Mesh(); | |
meshFilter.mesh = mesh; | |
UpdateMeshSize(); | |
} | |
public void UpdateMeshSize() | |
{ | |
Vertices = GenVerts(rows, columns); | |
Indices = GenStripIndices(rows, columns); | |
UVs = GenTexCoords(rows, columns, uvScale); | |
mesh.Clear(); | |
mesh.vertices = Vertices; | |
mesh.uv = UVs; | |
mesh.SetTriangleStrip(Indices, 0); | |
mesh.RecalculateNormals(); | |
mesh.RecalculateBounds(); | |
mesh.Optimize(); | |
} | |
public void UpdateVertices() | |
{ | |
mesh.vertices = Vertices; | |
mesh.RecalculateNormals(); | |
mesh.RecalculateBounds(); | |
} | |
public void UpdateUVs() | |
{ | |
mesh.uv = UVs; | |
mesh.RecalculateNormals(); | |
} | |
public void StartVisitingVertices() | |
{ | |
VisitingVertices = true; | |
StartCoroutine(VisitVerticesInTriOrder()); | |
} | |
public void StopVisitingVertices() | |
{ | |
VisitingVertices = false; | |
} | |
public void ToggleVisitingVertices() | |
{ | |
if (VisitingVertices) { | |
StopVisitingVertices(); | |
} else { | |
StartVisitingVertices(); | |
} | |
} | |
private IEnumerator VisitVerticesInTriOrder() | |
{ | |
var vertMarker = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform; | |
vertMarker.localScale *= 0.4f; | |
while (true) { | |
int ctr = 0; | |
for (int i = 0; i < Indices.Length; i++) { | |
ctr++; | |
vertMarker.position = this.Vertices[Indices[i]]; | |
//if (ctr % 3 == 1) { | |
vertMarker.renderer.enabled = false; | |
yield return new WaitForSeconds(1/vertVisitSpeed * 0.5f); | |
if (!VisitingVertices) break; | |
vertMarker.renderer.enabled = true; | |
//} | |
yield return new WaitForSeconds(1 / vertVisitSpeed); | |
if (!VisitingVertices) break; | |
} | |
yield return new WaitForSeconds(1 / vertVisitSpeed); | |
if (!VisitingVertices) break; | |
} | |
Object.Destroy(vertMarker.gameObject); | |
} | |
private static Vector3[] GenVerts(int rows, int cols) | |
{ | |
var verts = new Vector3[rows * cols]; | |
float xpos; | |
float ypos = (rows-1) * -0.5f; | |
//var sb = new System.Text.StringBuilder("VERTICES YO:\n"); | |
for (int y = 0; y < rows; y++) { | |
xpos = -(cols-1) * 0.5f; | |
for (int x = 0; x < cols; x++) { | |
verts[y * cols + x] = new Vector3(xpos, 0, ypos); | |
xpos += 1.0f; | |
//sb.Append("$(y * cols + x):[$(x),$(y)]=($(xpos),$(ypos))\n") | |
} | |
ypos += 1.0f; | |
} | |
//Debug.Log(sb.ToString()) | |
return verts; | |
} | |
private static int[] GenStripIndices(int rows, int cols) | |
{ | |
int numIndices = 2*cols*rows - 2*cols + 2*rows - 2; | |
var indices = new int[numIndices]; | |
// Make triangle strips with degenerate triangles | |
// with shared vertices at bottom-left and top-right of strip | |
int index = 0; | |
for (int y = 0; y < rows - 1; y++) { | |
indices[index++] = y * cols + (cols - 1); | |
for (int x = cols - 1; x >= 0; x--) { | |
indices[index++] = y * cols + x; | |
indices[index++] = (y + 1) * cols + x; | |
} | |
indices[index++] = (y + 1) * cols; | |
} | |
return indices; | |
} | |
private static Vector2[] GenTexCoords(int rows, int cols, Vector2 uvScale) | |
{ | |
var texCoords = new Vector2[rows * cols]; | |
float vInc = 1.0f / (rows - 1) * uvScale.y; | |
float uInc = 1.0f / (cols - 1) * uvScale.x; | |
DebugUtils.LogFormat("UV inc: {0},{1}", uInc, vInc); | |
int uvIndex = 0; | |
float vVal = 0f; | |
float uVal; | |
for (int v = 0; v < rows; v++) { | |
uVal = 0f; | |
for (int u = 0; u < cols; u++) { | |
texCoords[uvIndex] = new Vector2(uVal, vVal); | |
uVal += uInc; | |
uvIndex++; | |
} | |
vVal += vInc; | |
} | |
return texCoords; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment