Procedural Mesh Help Please

Hi everyone. I know there is stuff out there for this and I have seen it but my problem is I still don’t quite understand how to get this done. The examples in the Unity Script Documentation aren’t very descriptive and I can understand most C# but can only program in JS so anything I don’t understand in JS isn’t going to make much more sense in C#.

Getting to the point finally I basically would like to know how to create a basic cube using four gameobjects transforms as the vertices (this just makes it easier for my brain to process the information for some reason).

Any help on this matter is greatly appreciated as I have been trying to go about making my own decal system for some time now and have made… well no progress at all.

Have you looked at the procedural example projects?

–Eric

Thanks for your reply. Yes I have gone through the examples multiple times but the extrusion scrip is in C# and I don’t understand the key points to making it work for some reason it just fly’s right past me.

Which parts specifically are you having problems with?

The mesh components I guess. I understand how to set the vertices but don’t really understand how to calculate normals or render the triangles.

The mesh class will calculate the normals for you (see the docs), and rendering is handled by the engine, so you generally don’t have to worry about that.

Here it sets the uv and the triangles but I don’t understand how to implement this into a useful situation and honestly I can’t even figure out how to render just one triangle.

Keep in mind that I’m by no stretch of the imagination a beginner with unity. I have completed multiple freelance jobs that required me to program things in JS and am in the final stages of completing an arcade style space shooter I built just in my free time. How this just completely escapes my grasp is baffling but I just can’t seem to figure out how to make it work. It’s really been quite frustrating.

Again, generally you don’t actually have to worry about the rendering yourself - Unity will take care of that for you.

Anyway, it looks that like that bit of code just expects you to assign mesh data manually in the inspector. For anything more involved (like what it sounds like you’re wanting to do), you’ll want to build the mesh data procedurally in code.

As mentioned earlier, the mesh class can compute the normals for you, so that basically leaves vertex positions, texture coordinates (if you need them), and triangle indices.

You can probably determine if the mesh has been built correctly without the texture coordinates, so I’d just start with vertex positions and triangle indices. As for those, can you describe in more detail what shape you’re wanting to create? (I know you mentioned cubes and decals, but a little more detail might help.)

To start off just a basic cube 4 sides of equal width and height maybe 1 unit for faces. I basically just want to get something visible on screen. and work from there. I think I don’t really understand what the triangle indices do.

By the way thanks for your patients, I know I’m not giving you much to work with but I don’t really need anything too specific just a basic knowledge of it.

Don’t you mean 6 sides?

Ah, ok.

Here’s the basic idea behind the triangle indices. As you know, modern hardware generally renders geometry in terms of individual triangles. Now, you could just describe each triangle in terms of three vertices, e.g.:

[0, 1, 2], [4, 5, 2], [2, 4, 2]

And graphics APIs such as OpenGL and Direct3D will in fact let you do that.

However, consider a cube. A cube has 8 unique vertices (not worrying about normals and texture coordinates for the moment), and 12 triangles. If we submit three vertices for each triangle, that’s 36 vertices total. On modern hardware however, sending data across the bus is one of the costlier things you can do, so it’s generally best to minimize the amount of data that needs to be transfered where possible. In this case, we’re obviously sending each vertex multiple times, so there’s some redundancy there that can be eliminated.

One way to eliminate the redundancy is only to send 8 vertices, and then send a set of integer indices, where each set of three indices describes a triangle. The indices themselves index into the vertex array; for the cube (for example), that means all the indices will be in the range [0, 7].

Here’s an even simpler example: a quad. The vertices and indices for a simple quad might be:

vertices: [0, 0], [0, 1], [1, 1], [1, 0]
indices: 0, 1, 2, 0, 2, 3

If you draw this out on paper, you should see how the indices describe the two triangles that make up the quad (assuming I didn’t mess anything up).

In actuality, a cube mesh will likely have at least 24 vertices anyway, since it’s likely that normals and texture coordinates will not be shared at the corners. But, for more complex meshes with many triangles, using triangle indices can drastically reduce the amount of data (since the vertices don’t need to be duplicated for each triangle).

Sorry if that explanation is overly elementary and I’m telling you stuff you already know, but it seemed like the easiest way to explain it. (Post back if that still doesn’t answer your questions though.)

Ok let me give this a try and I’ll let you know how it goes.

Hooray! It works! Thanks million for taking the time to explain this to me. If I finish this thing you’ll be getting a free copy!

This will construct a cube and set spherical uv mapping on it, if it helps:

using UnityEngine;
using System.Collections;

public class Cube : MonoBehaviour {
	MeshFilter mF;
	MeshRenderer mR;
	Mesh mesh;
	public Material mat;
	
	const ushort CUBE_VERTICES = 8;
	const ushort CUBE_TRIANGLES = 12;
	
	Vector3[] vertices;
	int[] indices;
	Vector3[] normals;
	Vector2[] uvs;

	// Use this for initialization
	void Start () {
		gameObject.AddComponent(typeof(MeshFilter));
		gameObject.AddComponent(typeof(MeshRenderer));
		mesh = GetComponent<MeshFilter>().mesh;
		
		//Vertices
		vertices = new Vector3[CUBE_VERTICES] 
		{	new Vector3(-1, 1, -1),	// 0
			new Vector3(1, 1, -1),		// 1
			new Vector3(-1, -1, -1),	// 2
			new Vector3(1, -1, -1),	// 3
			new Vector3(-1, 1, 1),		// 4
			new Vector3(1, 1, 1),		// 5
			new Vector3(-1, -1, 1),	// 6
			new Vector3(1, -1, 1)		// 7
		};
		mesh.vertices = vertices;
		
		//Indices
		indices = new int[CUBE_TRIANGLES*3]
		{	0, 1, 2,    // side 1
			2, 1, 3,
			4, 0, 6,    // side 2
			6, 0, 2,
			7, 5, 6,    // side 3
			6, 5, 4,
			3, 1, 7,    // side 4
			7, 1, 5,
			4, 5, 0,    // side 5
			0, 5, 1,
			3, 7, 2,    // side 6
			2, 7, 6,
		};
		mesh.triangles = indices;
		
		//Normals
		normals = new Vector3[CUBE_VERTICES];
		for(int i = 0; i < vertices.Length; i++) {
			normals[i] = vertices[i].normalized;
		}
		mesh.normals = normals;
		
		//UVs
		uvs = new Vector2[CUBE_VERTICES];
		for(int i = 0; i < uvs.Length; i++) {
			uvs[i].x = Mathf.Asin(vertices[i].normalized.x) / Mathf.PI + 0.5f;
			uvs[i].y = Mathf.Asin(vertices[i].normalized.y) / Mathf.PI + 0.5f;
		}
		mesh.uv = uvs;
		
		//Materials
		renderer.material = mat;
	
	}
	
	void Update () {
		
		for(int i = 0; i < vertices.Length; i++) {
			Debug.DrawRay(vertices[i], normals[i] * 2, Color.green);
		}
	}

}

Thanks for the help Aubergine but it’s in C# and while I can understand most of it I just can’t make much sense of the parts I’m still having trouble with.

Any specific passage you have problems with?
UnityScript aside of the declaration of arrays which would be var vertices : Vector3[ ]; and MeshFilter instead of typeof(MeshFilter) kind of specifics would be exactly the same

I don’t have any problems with syntax it’s just that I’ve never tried to script a procedural mesh before I started looking into making decals so I was just a bit unclear as to what everything was doing in the documentation example. Jesse answered most of the questions I had beautifully right now the only problem I’m having is that after making the box some of the triangles normals are facing the wrong way. At first I thought I could fix it just by changing the order of the indices but that only fixed the top and bottom. Still doesn’t work for any of the sides and it appears that one of the triangles is just not there.

Oh and now I’m getting log entries saying the Shader wants normals and texture coordinates but there are none. Not sure how to fix that.

Having the winding right can depending on surface be tricky. Normally you use the vector cross product to find out which direction the normal looks (the normal needs to look away from the center basically, so somePoint + normal - center must have a larger magnitude than somePoint - center). that way you can find out the order in which the vertices need to be added

Regarding the ‘shader wants normals and texture coordinates’ message, try calling RecalculateNormals() on the mesh after you’ve assigned vertices and triangle indices. Also, try assigning an array of the appropriate size (that is, the same size as the vertex array) filled entirely with the zero vector to the ‘uv’ field of the mesh. This probably won’t give you the texture mapping results you want, but it should cause the warning message to go away.

Regarding the missing and incorrectly oriented triangles, that’s probably just a matter of getting your data right. Assuming you’re using a ‘one-sided’ shader, make sure that all of the triangles are wound consistently (should be clockwise, most likely) when viewed from the outside.

Regarding C# vs. UnityScript, don’t let that throw you - C# isn’t some mysterious, arcane language :wink: A lot will carry over as is from C# to UnityScript and vice versa, and anything that doesn’t you can always ask about here on the forums. (I know you said you can understand most of the C# code, but whatever it is that’s hanging you up, you should be able to figure out with help from the forums.)