- Home /
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:
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:
However it isn't wrapping around the cube correctly all the way around the cube:
And throwing in a different 'textureId' for one of the sides has even stranger results:
Hopefully someone on here will be able to help me with this because it's beginning to drive me up the wall :|
Many thanks in advance, AggroPanda
Answer by Cameron_SM · Dec 04, 2011 at 02:19 PM
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.
Your answer
Follow this Question
Related Questions
Does a Mesh Vertices/Triangles/etc Have to be Compact 1 Answer
Realtime C++ Unity Interaction 0 Answers
Procedurally Generated Cube Mesh 3 Answers
Sphere made of cubes algorithm 4 Answers
Polygon buffering/offsetting? 1 Answer