Texture-Atlas Modifying Mesh UVs

I am trying to combine multiple textures into a texture atlas using Texture2D.PackTextures() which works fine. I create a new material for all the materials used on my mesh and sub-meshes. I end up with a new Packed Texture with 4 images.

This new material using the texture atlas is then applied to all my mesh and submeshes.

I then modify the UVs of my mesh and submeshes to point to the new image within the texture atlas. But what I seem to get is the complete texture atlas being used as the single texture, rather than the image within the atlas.

This is what I am expecting (apologies for the dark colours, there's no lights in my test scene!):

alt text

And this is what I get:

alt text

I've checked the UVs and they look to be getting updated correctly.

Any ideas as to what I'm missing?

This is my code snippet, its nothing fancy.

Material atlasMaterial = new Material(Shader.Find("Diffuse Fast")); 
Component[] filters  = GetComponentsInChildren(typeof(MeshFilter)); 

Texture2D[] textures = new Texture2D[filters.Length]; 

for (int i=0 ; i<filters.Length ; i++) 
{ 
    textures _= (Texture2D)filters*.gameObject.renderer.material.mainTexture;*_ 
_*}*_ 
_*textureAtlas=new Texture2D(maxSquareTextureSize,maxSquareTextureSize);*_ 
_*Rect[] uvs = textureAtlas.PackTextures(textures,0,maxSquareTextureSize);*_ 
_*atlasMaterial.mainTexture = textureAtlas;*_ 
_*Vector2[] oldUV,newUV;*_ 
_*for (int i=0 ; i<filters.Length ; i++)*_ 
_*{*_ 
 <em>_filters*.gameObject.renderer.material=atlasMaterial;*_</em> 
 <em><em>_oldUV = (Vector2[])(((MeshFilter)filters*).mesh.uv);*_</em></em> 
 <em><em>_*newUV = new Vector2[oldUV.Length];*_</em></em> 
 <em><em>_*for (int j=0 ; j<oldUV.Length ; j++)*_</em></em>
 <em><em>_*{*_</em></em> 
 <em><em><em><em>newUV[j]=new Vector2((oldUV[j].x*uvs_.width)+uvs*.x,*_</em></em></em></em> 
 <em><em><em><em><em><em>(oldUV[j].y*uvs_.height)+uvs*.y);*_</em></em></em></em></em></em> 
 <em><em><em><em><em><em>_*}*_</em></em></em></em></em></em> 
 <em><em><em><em><em><em><em>_((MeshFilter)filters*).mesh.uv=newUV;*_</em></em></em></em></em></em></em> 
<em><em><em><em><em><em><em>_*}*_</em></em></em></em></em></em></em> 
<em><em><em><em><em><em><em>_*```*_</em></em></em></em></em></em></em>

It might be this line:

((MeshFilter)filters*).mesh.uv=newUV;* 
*```*
*<p>In general, you should use .sharedMesh wherever you're using .mesh right now; the latter acts like a value-type and returns a copy, which is probably not what you want.</p>*

My bet is that the textures array being packed wasn't full of single occurrence items (like in a Set). This code has the fundamental assumption that there is a 1:1 correspondence between texture, rectangle, and meshfilter, when this may not be the case at all.

First a verified Set of Texture2D should be used as the input textures. Then when choosing a rectangle for any particular Mesh, make sure to get the proper index into the Rectangles array using the Mesh's texture, with Array.IndexOf.

This also means that the various game objects should not be set to the new material until the UV's have been adjusted, since the mainTexture is needed to do the rectangle lookup.

I realize this is an old question, but figured someone might be wondering the same thing.