Skip to content

Instantly share code, notes, and snippets.

@tsaodown
Created May 17, 2016 21:45
Show Gist options
  • Save tsaodown/ba96be87eb7d50fc284a41f4621b964a to your computer and use it in GitHub Desktop.
Save tsaodown/ba96be87eb7d50fc284a41f4621b964a to your computer and use it in GitHub Desktop.
DerpCraft - Building a MineCraft Clone in Unity - Blocks | Full code available at https://git.io/vrlqL
using UnityEngine;
using Utilities;
public class Block {
public virtual MeshData GetBlockData(Vector3Int position,
MeshData collectedMeshData) {
collectedMeshData = FaceDataTop(position, collectedMeshData);
collectedMeshData = FaceDataBottom(position, collectedMeshData);
collectedMeshData = FaceDataNorth(position, collectedMeshData);
collectedMeshData = FaceDataSouth(position, collectedMeshData);
collectedMeshData = FaceDataEast(position, collectedMeshData);
collectedMeshData = FaceDataWest(position, collectedMeshData);
return collectedMeshData;
}
protected virtual MeshData FaceDataTop(Vector3Int position,
MeshData collectedMeshData) {
// top-left, top-right, bottom-right, bottom-left
collectedMeshData.AddVertex(new Vector3(
position.x - 0.5f, position.y + 0.5f, position.z + 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x + 0.5f, position.y + 0.5f, position.z + 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x + 0.5f, position.y + 0.5f, position.z - 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x - 0.5f, position.y + 0.5f, position.z - 0.5f));
// Add tris from verts.
collectedMeshData.AddQuadTriangles();
return collectedMeshData;
}
protected virtual MeshData FaceDataBottom(Vector3Int position,
MeshData collectedMeshData) {
// top-left, top-right, bottom-right, bottom-left
collectedMeshData.AddVertex(new Vector3(
position.x - 0.5f, position.y - 0.5f, position.z - 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x + 0.5f, position.y - 0.5f, position.z - 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x + 0.5f, position.y - 0.5f, position.z + 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x - 0.5f, position.y - 0.5f, position.z + 0.5f));
// Add tris from verts.
collectedMeshData.AddQuadTriangles();
return collectedMeshData;
}
protected virtual MeshData FaceDataNorth(Vector3Int position,
MeshData collectedMeshData) {
// top-left, top-right, bottom-right, bottom-left
collectedMeshData.AddVertex(new Vector3(
position.x + 0.5f, position.y + 0.5f, position.z + 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x - 0.5f, position.y + 0.5f, position.z + 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x - 0.5f, position.y - 0.5f, position.z + 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x + 0.5f, position.y - 0.5f, position.z + 0.5f));
// Add tris from verts.
collectedMeshData.AddQuadTriangles();
return collectedMeshData;
}
protected virtual MeshData FaceDataSouth(Vector3Int position,
MeshData collectedMeshData) {
// top-left, top-right, bottom-right, bottom-left
collectedMeshData.AddVertex(new Vector3(
position.x - 0.5f, position.y + 0.5f, position.z - 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x + 0.5f, position.y + 0.5f, position.z - 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x + 0.5f, position.y - 0.5f, position.z - 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x - 0.5f, position.y - 0.5f, position.z - 0.5f));
// Add tris from verts.
collectedMeshData.AddQuadTriangles();
return collectedMeshData;
}
protected virtual MeshData FaceDataEast(Vector3Int position,
MeshData collectedMeshData) {
// top-left, top-right, bottom-right, bottom-left
collectedMeshData.AddVertex(new Vector3(
position.x + 0.5f, position.y + 0.5f, position.z - 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x + 0.5f, position.y + 0.5f, position.z + 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x + 0.5f, position.y - 0.5f, position.z + 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x + 0.5f, position.y - 0.5f, position.z - 0.5f));
// Add tris from verts.
collectedMeshData.AddQuadTriangles();
return collectedMeshData;
}
protected virtual MeshData FaceDataWest(Vector3Int position,
MeshData collectedMeshData) {
// top-left, top-right, bottom-right, bottom-left
collectedMeshData.AddVertex(new Vector3(
position.x - 0.5f, position.y + 0.5f, position.z + 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x - 0.5f, position.y + 0.5f, position.z - 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x - 0.5f, position.y - 0.5f, position.z - 0.5f));
collectedMeshData.AddVertex(new Vector3(
position.x - 0.5f, position.y - 0.5f, position.z + 0.5f));
// Add tris from verts.
collectedMeshData.AddQuadTriangles();
return collectedMeshData;
}
}
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshCollider))]
public class BlockDisplay : MonoBehaviour {
Block block;
// Use this for initialization
void Start() {
block = new Block();
MeshData meshData = new MeshData();
meshData = block.GetBlockData(transform.position, meshData);
meshData.RecalculateNormals();
var filter = GetComponent<MeshFilter>();
filter.mesh.vertices = meshData.verts.ToArray();
filter.mesh.triangles = meshData.tris.ToArray();
filter.mesh.normals = meshData.normals.ToArray();
var coll = GetComponent<MeshCollider>();
var collMesh = new Mesh();
collMesh.vertices = meshData.colliderVerts.ToArray();
collMesh.triangles = meshData.colliderTris.ToArray();
collMesh.normals = meshData.colliderNormals.ToArray();
coll.sharedMesh = collMesh;
}
}
using UnityEngine;
using System.Collections.Generic;
public class MeshData {
public List<Vector3> verts = new List<Vector3>();
public List<int> tris = new List<int>();
public List<Vector3> normals = new List<Vector3>();
// Separate lists for collider vertices and triangles.
public List<Vector3> colliderVerts = new List<Vector3>();
public List<int> colliderTris = new List<int>();
public List<Vector3> colliderNormals = new List<Vector3>();
// Flag to use the same data for both mesh and collision.
public bool useRenderDataForCollision = true;
// Adds triangles to represent a quad made from the last 4
// vertices that were added.
public void AddQuadTriangles() {
/**
* 0 1
* -----
* |\ |
* | \ |
* | \|
* -----
* 3 2
* Uses clockwise winding.
**/
// Triangle for 0 -> 1 -> 2
tris.Add(verts.Count - 4);
tris.Add(verts.Count - 3);
tris.Add(verts.Count - 2);
Vector3 v1 = verts[verts.Count - 3] - verts[verts.Count - 4];
Vector3 v2 = verts[verts.Count - 2] - verts[verts.Count - 4];
Vector3 normal = Vector3.Cross(v1, v2).normalized;
normals[normals.Count - 4] += normal;
normals[normals.Count - 3] += normal;
normals[normals.Count - 2] += normal;
// Add the same for collision if necessary.
if (useRenderDataForCollision) {
colliderTris.Add(colliderVerts.Count - 4);
colliderTris.Add(colliderVerts.Count - 3);
colliderTris.Add(colliderVerts.Count - 2);
colliderNormals[colliderNormals.Count - 4] += normal;
colliderNormals[colliderNormals.Count - 3] += normal;
colliderNormals[colliderNormals.Count - 2] += normal;
}
// Triangle for 0 -> 2 -> 3
tris.Add(verts.Count - 4);
tris.Add(verts.Count - 2);
tris.Add(verts.Count - 1);
v1 = verts[verts.Count - 2] - verts[verts.Count - 4];
v2 = verts[verts.Count - 1] - verts[verts.Count - 4];
normal = Vector3.Cross(v1, v2).normalized;
normals[normals.Count - 4] += normal;
normals[normals.Count - 2] += normal;
normals[normals.Count - 1] += normal;
// Add the same for collision if necessary.
if (useRenderDataForCollision) {
colliderTris.Add(colliderVerts.Count - 4);
colliderTris.Add(colliderVerts.Count - 2);
colliderTris.Add(colliderVerts.Count - 1);
colliderNormals[colliderNormals.Count - 4] += normal;
colliderNormals[colliderNormals.Count - 2] += normal;
colliderNormals[colliderNormals.Count - 1] += normal;
}
}
// Adds vertex to mesh verts and optionally collider verts.
public void AddVertex(Vector3 v3) {
verts.Add(v3);
normals.Add(Vector3.zero);
if (useRenderDataForCollision) {
colliderVerts.Add(v3);
colliderNormals.Add(Vector3.zero);
}
}
// Adds triangle to mesh tris and optionally collider tris.
public void AddTriangle(int i) {
tris.Add(i);
if (useRenderDataForCollision)
colliderTris.Add(i - (verts.Count - colliderVerts.Count));
}
public void RecalculateNormals() {
for (int i = 0; i < normals.Count; i++) {
normals[i].Normalize();
if (useRenderDataForCollision)
colliderNormals[i].Normalize();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment