- Home /
Procedural Box: Only the first face is displayed
Hi,
I'm trying to generate a box procedurally. Everything is almost working, except I have only one face showing up, and it's always the first face to be processed. Here is my code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class BlockPart : MonoBehaviour
{
MeshFilter filter;
Renderer myRenderer;
public Vector3 dimensions;
public Texture2D tex;
public List<Vector3> vertices;
public List<int> triangles;
public List<Vector3> normals;
public List<Vector2> uv;
List<Vector3> tmpVert = new List<Vector3>();
List<int> tmpTris = new List<int>();
List<Vector3> tmpNorm = new List<Vector3>();
List<Vector2> tmpUvs = new List<Vector2>();
public float myAngle = 0;
void Awake()
{
dimensions = new Vector3(1, 2.2f, 1);
filter = GetComponent<MeshFilter>();
myRenderer = GetComponent<Renderer>();
}
public void reinit()
{
filter.mesh = new Mesh();
vertices = new List<Vector3>();
triangles = new List<int>();
normals = new List<Vector3>();
uv = new List<Vector2>();
}
public void addPane(Vector3 norm, Vector3 first, Vector3 second, Vector3 third, Vector3 forth)
{
tmpVert = new List<Vector3>() { new Vector3(), new Vector3(), new Vector3(), new Vector3() };
tmpTris = new List<int>() { 0, 0, 0, 0, 0, 0 };
tmpNorm = new List<Vector3>() { new Vector3(), new Vector3(), new Vector3(), new Vector3() };
tmpUvs = new List<Vector2>() { new Vector2(), new Vector2(), new Vector2(), new Vector2() };
tmpVert[0] = first;
tmpVert[1] = second;
tmpVert[2] = third;
tmpVert[3] = forth;
tmpTris[0] = 0;
tmpTris[1] = 1;
tmpTris[2] = 2;
tmpTris[3] = 0;
tmpTris[4] = 2;
tmpTris[5] = 3;
tmpNorm[0] = norm;
tmpNorm[1] = norm;
tmpNorm[2] = norm;
tmpNorm[3] = norm;
tmpUvs[0] = new Vector2(0, 0);
tmpUvs[1] = new Vector2(0, 1);
tmpUvs[2] = new Vector2(1, 1);
tmpUvs[3] = new Vector2(1, 0);
vertices.AddRange(tmpVert);
triangles.AddRange(tmpTris);
normals.AddRange(tmpNorm);
uv.AddRange(tmpUvs);
}
public Vector3 newV(float x, float y, float z)
{
return new Vector3(x, y, z);
}
public void addBox()
{
}
public Vector3 RotatePointAroundPivot(Vector3 point, float angle)
{
return Quaternion.AngleAxis(angle, Vector3.up) * point;
}
void createMesh()
{
filter.mesh.vertices = vertices.ToArray();
filter.mesh.normals = normals.ToArray();
filter.mesh.uv = uv.ToArray();
filter.mesh.triangles = triangles.ToArray();
myRenderer.material.mainTexture = tex;
filter.mesh.RecalculateBounds();
filter.mesh.RecalculateNormals();
filter.mesh.Optimize();
}
void Update ()
{
// Here, no matter what I do the first call on "addPane" will be the only one to be drawn
myAngle += Time.deltaTime * 5f;
reinit();
addPane(-Vector3.forward,
newV(-0.05f, 0, -0.05f),
newV(-0.05f, 2.2f, -0.05f),
newV(0.05f, 2.2f, -0.05f),
newV(0.05f, 0, -0.05f));
addPane(Vector3.forward,
newV(0.05f, 0, 0.05f),
newV(0.05f, 2.2f, 0.05f),
newV(-0.05f, 2.2f, 0.05f),
newV(-0.05f, 0, 0.05f));
addPane(-Vector3.left,
newV(-0.05f, 0, 0.05f),
newV(-0.05f, 2.2f, 0.05f),
newV(-0.05f, 2.2f, -0.05f),
newV(-0.05f, 0, -0.05f));
addPane(Vector3.right,
newV(0.05f, 0, -0.05f),
newV(0.05f, 2.2f, -0.05f),
newV(0.05f, 2.2f, 0.05f),
newV(0.05f, 0, 0.05f));
createMesh();
}
}
I've tried several approaches and I am running out of ideas.
edit: Separately, the faces are correct. They are all clockwise, display correctly with the proper UV, normals and triangles.
Thanks for your help.
What debugging steps have you tried? Debug.Log to make sure your verts/tris/norms lists have the expected number of items? Commenting out the first two panes to see if you can get a single side face to show up?
Btw one of your side panes is wrong - you passed them the same normal (-left and +right are both +right).
Answer by NoseKills · Apr 14, 2017 at 04:29 PM
At least you never add numbers beyond 0-3 to your triangles array, so those are the only 4 vertices you use to draw geometry
...
tmpTris[0] = 0;
tmpTris[1] = 1;
tmpTris[2] = 2;
tmpTris[3] = 0;
tmpTris[4] = 2;
tmpTris[5] = 3;
...
For every face you draw, you have to add 4 to the index from which you start the next time.