Custom Mesh UV Problem

Hi Everyone,

First off I’d like to say that I’m new to Unity (only been using it for about 2 months) therefore please forgive any terminology I use incorrectly (however please feel free to correct me).

Right, please bare with me on this one, however the problem I’m having is that I want to programatically create a texture and apply a different region of it to different sides of the cube. I’m creating my texture in the following way:

    // Create 6 textures (1 for each side)
	Texture2D texture1 = new Texture2D(32,32);
	Texture2D texture2 = new Texture2D(32,32);
	Texture2D texture3 = new Texture2D(32,32);
	Texture2D texture4 = new Texture2D(32,32);
	Texture2D texture5 = new Texture2D(32,32);
	Texture2D texture6 = new Texture2D(32,32);	
			
	for (int i = 0; i < 32; i++) {
		for (int j = 0; j < 32; j++) {
			if (i == 0 ||
			    j == 0 ||
			    i == 31 ||
			    j == 31) {					
				texture1.SetPixel(i,j,new Color(0,0,0));
				texture2.SetPixel(i,j,new Color(0,0,0));
				texture3.SetPixel(i,j,new Color(0,0,0));
				texture4.SetPixel(i,j,new Color(0,0,0));
				texture5.SetPixel(i,j,new Color(0,0,0));
				texture6.SetPixel(i,j,new Color(0,0,0));
				continue;
			}
			
			texture1.SetPixel(i,j,new Color(0,0,1));
			texture2.SetPixel(i,j,new Color(0,1,0));
			texture3.SetPixel(i,j,new Color(1,0,0));
			texture4.SetPixel(i,j,new Color(0,1,1));
			texture5.SetPixel(i,j,new Color(1,0,1));
			texture6.SetPixel(i,j,new Color(1,1,0));
		}
	}
	
	texture1.Apply();
	texture2.Apply();
	texture3.Apply();
	texture4.Apply();
	texture5.Apply();
	texture6.Apply();
	
	// Put all the textures into a signal list of textures
	textures = new Texture2D[] {
		texture1,
		texture2,
		texture3,
		texture4,
		texture5,
		texture6
	};
	
	// Pack the textures
	texture = new Texture2D(1024, 1024);
	textureUVs = texture.PackTextures(textures, 0, 1024);

This produces a texture like so:

alt text

I then apply this texture to my Mesh like this:

    this.renderer.material.mainTexture = texture;
	this.renderer.material.mainTexture.mipMapBias = -0.5f;
	this.renderer.material.mainTexture.filterMode = FilterMode.Point;
	this.renderer.material.mainTexture.wrapMode = TextureWrapMode.Clamp;
	this.renderer.material.color = new Color(1,1,1,1);

I then get the mesh from the MeshFilter like this:

    MeshFilter meshFilter = (MeshFilter)GetComponent("MeshFilter");
	Mesh mesh = meshFilter.mesh;

And apply the UV mappings like this:

    float epsilon = 0.000f; // Don't go right up to the edge of the texture		
	int textureId = 3; // Which texture would you like to use	
	
	Debug.Log("H: " + textureUVs[textureId].height + "W" + textureUVs[textureId].width);
	
	mesh.uv = new Vector2[]{
		new Vector2(textureUVs[textureId].x + epsilon, textureUVs[textureId].y + epsilon),
		new Vector2(textureUVs[textureId].x + textureUVs[textureId].width - epsilon, textureUVs[textureId].y + textureUVs[textureId].height - epsilon),
		new Vector2(textureUVs[textureId].x + textureUVs[textureId].width - epsilon, textureUVs[textureId].y + epsilon),
		new Vector2(textureUVs[textureId].x + epsilon, textureUVs[textureId].y + textureUVs[textureId].height - epsilon),
		
		new Vector2(textureUVs[textureId].x + epsilon, textureUVs[textureId].y + epsilon),
		new Vector2(textureUVs[textureId].x + textureUVs[textureId].width - epsilon, textureUVs[textureId].y + textureUVs[textureId].height - epsilon),
		new Vector2(textureUVs[textureId].x + textureUVs[textureId].width - epsilon, textureUVs[textureId].y + epsilon),
		new Vector2(textureUVs[textureId].x + epsilon, textureUVs[textureId].y + textureUVs[textureId].height - epsilon),
		
		new Vector2(textureUVs[textureId].x + epsilon, textureUVs[textureId].y + epsilon),
		new Vector2(textureUVs[textureId].x + textureUVs[textureId].width - epsilon, textureUVs[textureId].y + textureUVs[textureId].height - epsilon),
		new Vector2(textureUVs[textureId].x + textureUVs[textureId].width - epsilon, textureUVs[textureId].y + epsilon),
		new Vector2(textureUVs[textureId].x + epsilon, textureUVs[textureId].y + textureUVs[textureId].height - epsilon),
				
		new Vector2(textureUVs[textureId].x + epsilon, textureUVs[textureId].y + epsilon),
		new Vector2(textureUVs[textureId].x + textureUVs[textureId].width - epsilon, textureUVs[textureId].y + textureUVs[textureId].height - epsilon),
		new Vector2(textureUVs[textureId].x + textureUVs[textureId].width - epsilon, textureUVs[textureId].y + epsilon),
		new Vector2(textureUVs[textureId].x + epsilon, textureUVs[textureId].y + textureUVs[textureId].height - epsilon),
		
		new Vector2(textureUVs[textureId].x + epsilon, textureUVs[textureId].y + epsilon),
		new Vector2(textureUVs[textureId].x + textureUVs[textureId].width - epsilon, textureUVs[textureId].y + textureUVs[textureId].height - epsilon),
		new Vector2(textureUVs[textureId].x + textureUVs[textureId].width - epsilon, textureUVs[textureId].y + epsilon),
		new Vector2(textureUVs[textureId].x + epsilon, textureUVs[textureId].y + textureUVs[textureId].height - epsilon),
		
		new Vector2(textureUVs[textureId].x + epsilon, textureUVs[textureId].y + epsilon),
		new Vector2(textureUVs[textureId].x + textureUVs[textureId].width - epsilon, textureUVs[textureId].y + textureUVs[textureId].height - epsilon),
		new Vector2(textureUVs[textureId].x + textureUVs[textureId].width - epsilon, textureUVs[textureId].y + epsilon),
		new Vector2(textureUVs[textureId].x + epsilon, textureUVs[textureId].y + textureUVs[textureId].height - epsilon)
	};
			
	mesh.Optimize();
	mesh.RecalculateNormals();
	mesh.RecalculateBounds();

I would have thought that this would display the same texture on all 6 sides of the cube, like on this side:

alt text

However it isn’t wrapping around the cube correctly all the way around the cube:

alt text

And throwing in a different ‘textureId’ for one of the sides has even stranger results:

alt text

Hopefully someone on here will be able to help me with this because it’s beginning to drive me up the wall :expressionless:

Many thanks in advance,
AggroPanda

Looks like it’s working fine just that the underlying vertex order of the mesh is probably not lining up with how you’re assigning UVs.

A simple way to fix this would be to assign vertex colors so you can see what order the vertices are in. Create a new material (Particles/Alpha Blaneded will work well for this.), leave the texture channel blank and do the following in script:

mesh.colors = new Color{

   // Side 1 (we think)
   Color.red,    // uv 0,0
   Color.green,  // uv 1,0
   Color.blue,   // uv 1,1
   Color.yellow, // uv 0,1

   // Side 2?
   Color.black,
   Color.black,
   Color.black,
   Color.black,

   Color.black,
   Color.black,
   Color.black,
   Color.black,

   Color.black,
   Color.black,
   Color.black,
   Color.black,

   Color.black,
   Color.black,
   Color.black,
   Color.black,

   Color.black,
   Color.black,
   Color.black,
   Color.black,

};

Then start shifting the color values around and adding/editing comments to what colors you see where until you’ve identified each face and corner vertex. After that translating your packed uv’s across should be a piece of cake.