i’m trying to generate a simple dynamic mesh but i’m at a loss as to why it doesn’t work properly.
the following code is attached to an empty gameobject and the scene has a light and a camera and a simple texture on it just to try and better see what is going on with my triangles.
as is, the code generates 2 triangles that make a square. the first triangle shows up, but is backwards (from the camera direction it is invisible but from behind it shows up) and the second triangle is just not there at all.
i tried using the RecalculateNormals() function and it gave me one backwards normal (0,-1,0) and a zero vector (0,0,0). so now i make my own normals but the visual end result is the same even though the normals are now correct (0,1,0).
i’ve stepped through the code in the debugger and can see that the vertices, the uv’s and the triangles all have what look like to be correct values but the end result is not correct visually. i’m just not sure what i’m doing wrong at this point.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class TerrainChunkGenerator : MonoBehaviour
{
public Material triMat;
Vector3 CalculateNormal(Vector3 p1, Vector3 p2, Vector3 p3)
{
Vector3 U = new Vector3( );
U = p2 - p1;
Vector3 V = new Vector3( );
V = p3 - p1;
int x = (int)(U.y * V.z) - (int)(U.z * V.y);
int y = (int)(U.z * V.x) - (int)(U.x * V.z);
int z = (int)(U.x * V.y) - (int)(U.y * V.x);
Vector3 normal = new Vector3(x, y, z);
return normal;
}
Mesh ChunkMeshGenerator(int gridUnits)
{
// generates chuck mesh (vertices, triangles, etc)
Mesh m = new Mesh();
int numVerts = (gridUnits + 1) * (gridUnits + 1);
Vector3[] vertArray = new Vector3[numVerts];
int vertsPerSide = gridUnits + 1;
// compute temp vertice array
int idx = 0;
for(int z = 0; z < vertsPerSide; z++)
{
for(int x = 0; x < vertsPerSide; x++)
{
Vector3 tempVert = new Vector3(x, 0, z);
//Vector3 tempVert = new Vector3(x, (Random.Range(-0.3f, 0.3f)), z);
vertArray[idx++] = tempVert;
}
}
// now populate vertex list with duplicated vertices for each point to allow for non-shared uv coords
int numTriVerts = gridUnits * gridUnits * 2 * 3;
Vector3[] meshVertArray = new Vector3[numTriVerts];
Vector2[] meshUvArray = new Vector2[numTriVerts];
int[] meshTriArray = new int[numTriVerts];
Vector3[] meshNormalArray = new Vector3[numTriVerts];
idx = 0;
for (int j = 0; j < gridUnits; j++)
{
for (int i = 0; i < gridUnits; i++)
{
int a, b, c, d;
a = vertsPerSide * j + i;
b = a + vertsPerSide;
c = a + 1;
d = b + 1;
meshVertArray[idx] = vertArray[c];
meshUvArray[idx] = new Vector2(1,0);
meshTriArray[idx] = c;
meshNormalArray[idx] = CalculateNormal( vertArray[c], vertArray[a], vertArray[b] );
idx++;
meshVertArray[idx] = vertArray[a];
meshUvArray[idx] = new Vector2(0,0);
meshTriArray[idx] = a;
meshNormalArray[idx] = meshNormalArray[idx - 1];
idx++;
meshVertArray[idx] = vertArray[b];
meshUvArray[idx] = new Vector2(0,1);
meshTriArray[idx] = b;
meshNormalArray[idx] = meshNormalArray[idx - 1];
idx++;
meshVertArray[idx] = vertArray[b];
meshUvArray[idx] = new Vector2(0,1);
meshTriArray[idx] = b;
meshNormalArray[idx] = CalculateNormal( vertArray[b], vertArray[d], vertArray[c] );
idx++;
meshVertArray[idx] = vertArray[d];
meshUvArray[idx] = new Vector2(1,1);
meshTriArray[idx] = d;
meshNormalArray[idx] = meshNormalArray[idx - 1];
idx++;
meshVertArray[idx] = vertArray[c];
meshUvArray[idx] = new Vector2(1,0);
meshTriArray[idx] = c;
meshNormalArray[idx] = meshNormalArray[idx - 1];
idx++;
}
}
m.vertices = new Vector3[numTriVerts];
m.vertices = meshVertArray;
m.uv = new Vector2[numTriVerts];
m.uv = meshUvArray;
m.triangles = new int[numTriVerts];
m.triangles = meshTriArray;
m.normals = new Vector3[numTriVerts];
m.normals = meshNormalArray;
m.RecalculateBounds ();
m.Optimize();
return m;
}
// Use this for initialization
void Start ()
{
int ChunkGridSize = 1;
GameObject[,] terrain = new GameObject[ChunkGridSize, ChunkGridSize];
for(int x = 0; x < ChunkGridSize; x++)
{
for(int y = 0; y < ChunkGridSize; y++)
{
terrain[x,y] = new GameObject();
terrain[x,y].AddComponent<MeshFilter>();
terrain[x,y].AddComponent<MeshRenderer>();
terrain[x,y].AddComponent<MeshCollider>();
MeshFilter meshFilter = new MeshFilter();
meshFilter = terrain[x,y].GetComponent<MeshFilter>();
meshFilter.mesh = ChunkMeshGenerator(ChunkGridSize );
meshFilter.mesh.name = "mesh" + x.ToString() + y.ToString();
terrain[x,y].renderer.material = triMat;
terrain[x,y].transform.position = new Vector3(x * ChunkGridSize, 0, y*ChunkGridSize);
}
}
}
// Update is called once per frame
void Update ()
{
}
}
any help with getting this to work properly would be greatly appreciated.
this is what i see in the scene view while running the project if i swing the camera down and behind the gameobject.

and this is what the texture looks like.
