Skip to content

Instantly share code, notes, and snippets.

@cmaher
Last active May 29, 2021 16:27
Show Gist options
  • Save cmaher/905f15c09e4eeb95d9a031b974262d23 to your computer and use it in GitHub Desktop.
Save cmaher/905f15c09e4eeb95d9a031b974262d23 to your computer and use it in GitHub Desktop.
Honeycombed procedural grid of cubes -- I thought this would work for fog of war, but getting the right shader is another question
using System.Collections;
using System.Xml.Schema;
using UnityEngine;
// adapted from this series: https://catlikecoding.com/unity/tutorials/procedural-grid/
public class BoxGridMesh : MonoBehaviour {
public int length;
public int width;
public bool drawGizmos = false;
private Mesh mesh;
private Vector3[] verts;
private int height = 2;
private void Awake() {
Generate();
}
private void Generate() {
mesh = new Mesh {name = "Procedural Box Grid"};
GetComponent<MeshFilter>().mesh = mesh;
var planeVertSize = (length + 1) * (width + 1);
verts = new Vector3[planeVertSize * height];
var uv = new Vector2[verts.Length];
for (var y = 0; y < height; y++) {
for (int i = planeVertSize * y, z = 0; z <= width; z++) {
for (var x = 0; x <= length; x++, i++) {
verts[i] = new Vector3(x, y, z);
uv[i] = new Vector2((float) x / length, (float) z / width);
}
}
}
// (num cubes * 12 tris) = length * width * 36 verts
var tris = new int[length * width * 36];
var triIdx = 0;
// fill in the cubes row by row
for (var cubeZ = 0; cubeZ < width; cubeZ++) {
for (var cubeX = 0; cubeX < length; cubeX++) {
if ((cubeX > 10 && cubeX <= 20) || (cubeZ > 20 && cubeZ <= 30)) {
continue;
}
triIdx = SetCube(tris, triIdx, cubeX, cubeZ);
}
}
mesh.vertices = verts;
mesh.triangles = tris;
mesh.uv = uv;
}
// i = starting index to tris
// vXY = verts in quad coords (in clockwise order)
// wind clockwise
// returns the new triIdx
private static int SetQuad(int[] tris, int triIdx, int v00, int v01, int v11, int v10) {
// tri 1
tris[triIdx] = v00;
tris[triIdx + 1] = v01;
tris[triIdx + 2] = v10;
// tri 2
tris[triIdx + 3] = v10;
tris[triIdx + 4] = v01;
tris[triIdx + 5] = v11;
return triIdx + 6;
}
private int SetCube(int[] tris, int triIdx, int cubeX, int cubeZ) {
// bottom 4 verts, clockwise
var v000 = VertIdx(cubeX, 0, cubeZ); // idx 0
var v001 = VertIdx(cubeX, 0, cubeZ + 1); // idx 2
var v101 = VertIdx(cubeX + 1, 0, cubeZ + 1); // idx 3
var v100 = VertIdx(cubeX + 1, 0, cubeZ); // idx 1
// top 4 verts, clockwise
var v010 = VertIdx(cubeX, 1, cubeZ); // idx 4
var v011 = VertIdx(cubeX, 1, cubeZ + 1); // idx 6
var v111 = VertIdx(cubeX + 1, 1, cubeZ + 1); // idx 7
var v110 = VertIdx(cubeX + 1, 1, cubeZ); // idx 5
// bottom face = anticlockwise bottom quad
triIdx = SetQuad(tris, triIdx, v100, v101, v001, v000);
// top face = clockwise top quad
triIdx = SetQuad(tris, triIdx, v010, v011, v111, v110);
// front face
triIdx = SetQuad(tris, triIdx, v000, v010, v110, v100);
// right face
triIdx = SetQuad(tris, triIdx, v100, v110, v111, v101);
// back face
triIdx = SetQuad(tris, triIdx, v101, v111, v011, v001);
// left face
triIdx = SetQuad(tris, triIdx, v001, v011, v010, v000);
return triIdx;
}
// Verts are stored in a 1D array, 1 row at a time
private int VertIdx(int x, int y, int z) {
return x + z * (length + 1) + (y * (length + 1) * (width + 1));
}
#if UNITY_EDITOR
private void OnDrawGizmos() {
if (!drawGizmos) {
return;
}
if (verts != null) {
Gizmos.color = Color.black;
for (var i = 0; i < verts.Length; i++) {
Gizmos.DrawSphere(transform.TransformPoint(verts[i]), 0.1f);
}
}
}
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment