- Home /
Getting meshes to render properly, and coloring triangles of a mesh
I am wondering how to ensure that all sides of a mesh are visible always.
My mesh is a "card" made of voxels that is basically a 2D array of voxels where cardWidth = 63 and cardHeight = 88. After generating the mesh if I rotate it certain ways certain sides of the mesh do not render.
I understand from looking around that I might have to calculate my normal vectors differently to get my desired result but I am confused on how that all works.
I also am looking to move on to coloring each cube individually which, unless I have no idea what I'm talking about, should be "easier" since I am not sharing vertices between my triangles. Ideally, in my mind, I would call a method colorSquare(int x, int y, color) and then be able to extend it from there for whatever purposes.
Whatever tips I could get on either Issue would be greatly appreciated. I like to think I have a solid grasp on programming but 3D and meshes is something I have yet to be able to wrap my head around, and I still would consider myself a new to Unity.
Thanks in advance! Below I have included my scripts for Card, Voxel, and MeshData if it helps at all.
Card:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshCollider))]
public class Card : MonoBehaviour {
Voxel[,] cardGraphics;
public static int cardHeight = 88;
public static int cardWidth = 63;
public bool update = true;
bool faceUp;
string name;
int cost;
int health;
int attack;
public Card(string name, int cost, int health, int attack)
{
this.name = name;
this.cost = cost;
this.health = health;
this.attack = attack;
}
MeshFilter filter;
MeshCollider coll;
public void Start()
{
filter = gameObject.GetComponent<MeshFilter>();
coll = gameObject.GetComponent<MeshCollider>();
cardGraphics = new Voxel[cardWidth, cardHeight];
for (int x = 0; x < cardWidth; x++)
{
for (int y = 0; y < cardHeight; y++)
{
cardGraphics[x, y] = new Voxel();
}
}
//cardGraphics[3, 5] = new Voxel();
UpdateCard();
}
public Voxel GetVoxel(int x, int y)
{
return cardGraphics[x, y];
}
void UpdateCard()
{
MeshData meshData = new MeshData();
for (int x = 0; x < cardWidth; x++)
{
for (int y = 0; y < cardHeight; y++)
{
meshData = cardGraphics[x, y].Voxeldata(this, x, y, meshData);
}
}
RenderMesh(meshData);
}
void RenderMesh(MeshData meshData)
{
filter.mesh.Clear();
filter.mesh.vertices = meshData.vertices.ToArray();
filter.mesh.triangles = meshData.triangles.ToArray();
filter.mesh.uv = meshData.uv.ToArray();
filter.mesh.RecalculateNormals();
}
}
Voxel
public class Voxel
{
public enum Direction { north, east, south, west, up, down };
public struct Colors { public int x; public int y; }
const float colorSize = 0.25f;
public Voxel()
{
}
public virtual bool IsSolid(Direction direction)
{
switch (direction)
{
case Direction.north:
return true;
case Direction.east:
return true;
case Direction.south:
return true;
case Direction.west:
return true;
case Direction.up:
return true;
case Direction.down:
return true;
}
return false;
}
public virtual MeshData Voxeldata(Card card, int x, int y, MeshData meshData)
{
if (x == 0)
{
meshData = FaceDataWest(card, x, y, meshData);
}
if (y == 0)
{
meshData = FaceDataDown(card, x, y, meshData);
}
else if (x == Card.cardWidth)
{
meshData = FaceDataEast(card, x, y, meshData);
}
else if (y == Card.cardHeight)
{
meshData = FaceDataUp(card, x, y, meshData);
}
meshData = FaceDataNorth(card, x, y, meshData);
meshData = FaceDataSouth(card, x, y, meshData);
return meshData;
}
protected virtual MeshData FaceDataUp(Card card, int x, int y, MeshData meshData)
{
meshData.vertices.Add(new Vector3(x - 0.5f, y + 0.5f, 0 + 0.5f));
meshData.vertices.Add(new Vector3(x + 0.5f, y + 0.5f, 0 + 0.5f));
meshData.vertices.Add(new Vector3(x + 0.5f, y + 0.5f, 0 - 0.5f));
meshData.vertices.Add(new Vector3(x - 0.5f, y + 0.5f, 0 - 0.5f));
meshData.AddQuadTriangles();
return meshData;
}
protected virtual MeshData FaceDataDown(Card card, int x, int y, MeshData meshData)
{
meshData.vertices.Add(new Vector3(x - 0.5f, y - 0.5f, 0 - 0.5f));
meshData.vertices.Add(new Vector3(x + 0.5f, y - 0.5f, 0 - 0.5f));
meshData.vertices.Add(new Vector3(x + 0.5f, y - 0.5f, 0 + 0.5f));
meshData.vertices.Add(new Vector3(x - 0.5f, y - 0.5f, 0 + 0.5f));
meshData.AddQuadTriangles();
return meshData;
}
//remaining faces of voxel created in same way
}
MeshData
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MeshData
{
public List<Vector3> vertices = new List<Vector3>();
public List<int> triangles = new List<int>();
public List<Vector2> uv = new List<Vector2>();
public List<Vector3> colVertices = new List<Vector3>();
public List<int> colTriangles = new List<int>();
public MeshData() { }
public void AddQuadTriangles()
{
triangles.Add(vertices.Count - 4);
triangles.Add(vertices.Count - 3);
triangles.Add(vertices.Count - 2);
triangles.Add(vertices.Count - 4);
triangles.Add(vertices.Count - 2);
triangles.Add(vertices.Count - 1);
}
}
Two things to help you along:
The direction of a triangle's normal is deter$$anonymous$$ed by the order of it's vertices. If you have a triangle of three vertices:
0 = lower left, 1 = upper left, 2 = upper right
then the normal direction will be "towards you" if you see these vertices before you laid out. Basically, a clockwise vertex assignment. Counter-cockwise would face "away from you".
The easiest way to color triangles is probably to use a shader that supports vertex colors and use the mesh's colors array to give each vertex a color.
Your answer
Follow this Question
Related Questions
How to create a custom cuboids at runtime? 1 Answer
How to snap a Prefab to the normal of an irregular mesh 1 Answer
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Cube Voxel not working. Help please 1 Answer