Last active
April 20, 2024 07:11
-
-
Save Hotrian/8dfbe55afea456ebb7bd4489385e133c to your computer and use it in GitHub Desktop.
Example code for simple Quad and Cube meshes built through code.
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 System.Collections.Generic; | |
using UnityEngine; | |
[RequireComponent(typeof(MeshFilter)), RequireComponent(typeof(MeshRenderer))] | |
public class ProtoMesh : MonoBehaviour | |
{ | |
#region Helper Properties | |
// Simple helpers to cache the MeshFilter and MeshRenderer | |
public MeshRenderer MyMeshRenderer | |
{ | |
get { return _myMeshRenderer ?? (_myMeshRenderer = gameObject.GetComponent<MeshRenderer>()); } | |
} | |
public MeshFilter MyMeshFilter | |
{ | |
get { return _myMeshFilter ?? (_myMeshFilter = gameObject.GetComponent<MeshFilter>()); } | |
} | |
private MeshRenderer _myMeshRenderer; | |
private MeshFilter _myMeshFilter; | |
#endregion | |
#region Unity Methods | |
// Use this for initialization | |
void Start() | |
{ | |
GenerateMesh(); | |
} | |
#endregion | |
public void GenerateMesh() | |
{ | |
if (MyMeshFilter == null || MyMeshRenderer == null) | |
{ | |
Debug.LogError("MeshFilter/MeshRenderer Reference Lost!"); | |
return; | |
} | |
// Create lists to store our mesh data in | |
var vertices = new List<Vector3>(); | |
var triangles = new List<int>(); | |
var normals = new List<Vector3>(); | |
var uvs = new List<Vector2>(); | |
// Derived classes will fill the mesh data here | |
_generateMesh(vertices, triangles, normals, uvs); | |
// Generate a Mesh | |
var mesh = new Mesh | |
{ | |
vertices = vertices.ToArray(), | |
triangles = triangles.ToArray(), | |
normals = normals.ToArray(), | |
uv = uvs.ToArray() | |
}; | |
// Assign the Mesh | |
MyMeshFilter.mesh = mesh; | |
} | |
// Override in derived classes | |
protected virtual void _generateMesh(List<Vector3> vertices, List<int> triangles, List<Vector3> normals, List<Vector2> uvs) | |
{ | |
Debug.LogWarning("_generateMesh() isn't being overridden or base() is being called!"); | |
} | |
// Master class for simple geometry | |
public static class BaseMeshData | |
{ | |
const float TileSize = 1.001f; // 1f shows seams | |
#region Cube Data | |
/* | |
* 0 - Right - x+ | |
* 1 - Left - x- | |
* 2 - Top - y+ | |
* 3 - Bottom - y- | |
* 4 - Back - z+ | |
* 5 - Front - z- | |
*/ | |
public static readonly Vector3[][] CubeVerts = | |
{ | |
new[]{ new Vector3( TileSize, 0f, 0f), new Vector3(TileSize, 0f, TileSize), new Vector3(TileSize, TileSize, 0f), new Vector3(TileSize, TileSize, TileSize)}, | |
new[]{ new Vector3( 0f, 0f, TileSize), new Vector3(0f, 0f, 0f), new Vector3(0f, TileSize, TileSize), new Vector3(0f, TileSize, 0f)}, | |
new[]{ new Vector3( 0f, TileSize, 0f), new Vector3(TileSize, TileSize, 0f), new Vector3(0f, TileSize, TileSize), new Vector3(TileSize, TileSize, TileSize)}, | |
new[]{ new Vector3( TileSize, 0f, 0f), new Vector3(0f, 0f, 0f), new Vector3(TileSize, 0f, TileSize), new Vector3(0f, 0f, TileSize)}, | |
new[]{ new Vector3( TileSize, 0f, TileSize), new Vector3(0f, 0f, TileSize), new Vector3(TileSize, TileSize, TileSize), new Vector3(0f, TileSize, TileSize)}, | |
new[]{ new Vector3( 0f, 0f, 0f), new Vector3(TileSize, 0f, 0f), new Vector3(0f, TileSize, 0f), new Vector3(TileSize, TileSize, 0f)} | |
}; | |
public static readonly int[][] CubeTris = | |
{ | |
new[]{ 1, 0, 2, 2, 3, 1}, | |
new[]{ 1, 0, 2, 2, 3, 1}, | |
new[]{ 1, 0, 2, 2, 3, 1}, | |
new[]{ 1, 0, 2, 2, 3, 1}, | |
new[]{ 1, 0, 2, 2, 3, 1}, | |
new[]{ 1, 0, 2, 2, 3, 1} | |
}; | |
public static readonly Vector3[] CubeNorms = | |
{ | |
new Vector3( 1f, 0f, 0f), | |
new Vector3(-1f, 0f, 0f), | |
new Vector3( 0f, 1f, 0f), | |
new Vector3( 0f,-1f, 0f), | |
new Vector3( 0f, 0f, 1f), | |
new Vector3( 0f, 0f,-1f) | |
}; | |
public static readonly Vector2[][] CubeUVs = | |
{ | |
new[] { new Vector2( 0f, 0f), new Vector2( 1f, 0f), new Vector2( 0f, 1f), new Vector2( 1f, 1f)}, | |
new[] { new Vector2( 0f, 0f), new Vector2( 1f, 0f), new Vector2( 0f, 1f), new Vector2( 1f, 1f)}, | |
new[] { new Vector2( 0f, 0f), new Vector2( 1f, 0f), new Vector2( 0f, 1f), new Vector2( 1f, 1f)}, | |
new[] { new Vector2( 0f, 0f), new Vector2( 1f, 0f), new Vector2( 0f, 1f), new Vector2( 1f, 1f)}, | |
new[] { new Vector2( 0f, 0f), new Vector2( 1f, 0f), new Vector2( 0f, 1f), new Vector2( 1f, 1f)}, | |
new[] { new Vector2( 0f, 0f), new Vector2( 1f, 0f), new Vector2( 0f, 1f), new Vector2( 1f, 1f)}, | |
}; | |
#endregion | |
#region Quad Data | |
public static readonly Vector3[] QuadVerts = CubeVerts[5]; | |
public static readonly int[] QuadTris = CubeTris[5]; | |
public static readonly Vector3 QuadNorm = CubeNorms[5]; | |
public static readonly Vector2[] QuadUVs = CubeUVs[5]; | |
#endregion | |
} | |
} |
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 System.Collections.Generic; | |
using UnityEngine; | |
public class SimpleMeshCube : ProtoMesh | |
{ | |
protected override void _generateMesh(List<Vector3> vertices, List<int> triangles, List<Vector3> normals, List<Vector2> uvs) | |
{ | |
// Do not call base._generateMesh(); due to the Debug.LogWarning in the base method | |
// Generating a cube is a bit trickier, but it's basically generating a quad 6 times in different directions | |
// The thing to remember here, is that as we add more vertices we have to keep count so we know which | |
// vertices must be stitched together. | |
var count = 0; | |
// Loop through the faces of this Cube | |
for (var j = 0; j < BaseMeshData.CubeVerts.Length; j++) | |
{ | |
// Add the base data to the mesh, in this case we are adding quads to form a cube | |
vertices.AddRange(BaseMeshData.CubeVerts[j]); | |
uvs.AddRange(BaseMeshData.CubeUVs[j]); | |
// We must now manually add the indices because we are | |
// building multiple template quads together into a single mesh. | |
for (var i = 0; i < BaseMeshData.CubeTris[j].Length; i++) | |
{ | |
triangles.Add(count + BaseMeshData.CubeTris[j][i]); | |
} | |
// Because each of the vertices in a quad are facing the same direction, we just copy the one Normal direction for each vertex | |
// This cube is just 6 quads, so the operation is the same. | |
for (var i = 0; i < BaseMeshData.CubeVerts[j].Length; i++) | |
{ | |
normals.Add(BaseMeshData.CubeNorms[j]); | |
} | |
// We must count the number of vertices added in each step in order to | |
// stitch the next quad properly. | |
count += BaseMeshData.CubeVerts[j].Length; | |
} | |
} | |
} |
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 System.Collections.Generic; | |
using UnityEngine; | |
public class SimpleMeshQuad : ProtoMesh | |
{ | |
protected override void _generateMesh(List<Vector3> vertices, List<int> triangles, List<Vector3> normals, List<Vector2> uvs) | |
{ | |
// Do not call base._generateMesh(); due to the Debug.LogWarning in the base method | |
// Add the base data to the mesh | |
vertices.AddRange(BaseMeshData.QuadVerts); | |
triangles.AddRange(BaseMeshData.QuadTris); | |
uvs.AddRange(BaseMeshData.QuadUVs); | |
// Because each of the vertices in a quad are facing the same direction, we just copy the one Normal direction for each vertex | |
for (var i = 0; i < BaseMeshData.QuadVerts.Length; i++) | |
{ | |
normals.Add(BaseMeshData.QuadNorm); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment