I am making a tile puzzle game. Each tile is made of three segments, and I am changing their colours on the fly by setting UVs in code. (The mesh is built from scratch in code too). At Awake() I am filling an array with hard-coded UV settings, and then a ChangeColor(int,int,int) method returns a Vector2 which goes straight into the mesh’s uv settings. It is working fine in the editor, but when I build to test on my iPhone 4, the UVs get screwed around. I’ve attached a picture to illustrate. I’ve tried changing the import settings on the texture, and changing the shader. Same result. Is this a known problem? Am I doing something wrong?
Here’s the code that handles the mesh:
(By the way TriPos.height is a constant - the height of an equilateral triangle)
using UnityEngine;
using System.Collections;
public class TileData : MonoBehaviour {
// Holds info on UVs for all colors, trangled or not. Only a mono so it can init on its own
// Tile Prefab
//---------------------------------------------------------
public GameObject TilePrefab;
public static GameObject Prefab;
// Arrays to hold the information
//---------------------------------------------------------
private static Vector3[] verts;
private static int[] tris;
private static Vector2[,,] uvs; // for each color, for locked or not, for each vertex
public static readonly int colorCount = 9;
// Store hard coded data into arrays
//---------------------------------------------------------
void Awake () {
// Static access to prefab
Prefab = TilePrefab;
// Set Verts
verts = new Vector3[9];
verts[0] = Vector3.zero;
verts[1] = new Vector3( 0, TriPos.Height*(2f/3f), 0 );
verts[2] = new Vector3( 0.5f, -TriPos.Height/3f, 0 );
verts[3] = verts[0];
verts[4] = verts[2];
verts[5] = new Vector3( -0.5f, -TriPos.Height/3f, 0 );
verts[6] = verts[0];
verts[7] = verts[5];
verts[8] = verts[1];
// Set Tris
tris = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
// Set UVs for all colors, for unlocked/locked
// ??? needs to be sorted out
float h = TriPos.Height;
uvs = new Vector2[colorCount,2,3];
// color 0, locked
uvs[0,1,0] = new Vector2(0.25f, h/3f);
uvs[0,1,1] = new Vector2(0.25f, 0);
uvs[0,1,2] = new Vector2(0, h/2f);
// color 1, locked
uvs[1,1,0] = uvs[0,1,0];
uvs[1,1,1] = uvs[0,1,2];
uvs[1,1,2] = new Vector2(0.5f, h/2f);
// color 2, locked
uvs[2,1,0] = uvs[0,1,0];
uvs[2,1,1] = uvs[1,1,2];
uvs[2,1,2] = uvs[0,1,1];
// color 3, locked
uvs[3,1,0] = new Vector2(0.5f, h/6f);
uvs[3,1,1] = uvs[0,1,1];
uvs[3,1,2] = uvs[1,1,2];
// color 4, locked
uvs[4,1,0] = uvs[3,1,0];
uvs[4,1,1] = uvs[3,1,2];
uvs[4,1,2] = new Vector2(0.75f, 0);
// color 5, locked
uvs[5,1,0] = uvs[3,1,0];
uvs[5,1,1] = uvs[4,1,2];
uvs[5,1,2] = uvs[3,1,1];
// color 6, locked
uvs[6,1,0] = new Vector2(0.75f, h/3f);
uvs[6,1,1] = uvs[4,1,2];
uvs[6,1,2] = uvs[4,1,1];
// color 7, locked
uvs[7,1,0] = uvs[6,1,0];
uvs[7,1,1] = uvs[6,1,2];
uvs[7,1,2] = new Vector2(1, h/2f);
// color 8, locked
uvs[8,1,0] = uvs[6,1,0];
uvs[8,1,1] = uvs[7,1,2];
uvs[8,1,2] = uvs[6,1,1];
// Mirror along y==h/2 line for locked
for ( int c=0; c<colorCount; c++ ) {
for ( int v=0; v<3; v++ ) {
Vector2 untr = uvs[c,1,v];
uvs[c,0,v] = new Vector2( untr.x, h - untr.y);
}
}
}
// Get Verts from stored arrays
//---------------------------------------------------------
public static Vector3[] GetVerts() {
return verts;
}
// Get Tris from stored arrays
//---------------------------------------------------------
public static int[] GetTris() {
return tris;
}
// Get UVs from stored arrays
//---------------------------------------------------------
public static Vector2[] GetUVs( int c0, int c1, int c2, bool locked ) {
c0 = c0 % colorCount; c1 = c1 % colorCount; c2 = c2 % colorCount;
int tr = locked ? 1 : 0;
Vector2[] u = new Vector2[9];
u[0] = uvs[c0,tr,0];
u[1] = uvs[c0,tr,1];
u[2] = uvs[c0,tr,2];
u[3] = uvs[c1,tr,0];
u[4] = uvs[c1,tr,1];
u[5] = uvs[c1,tr,2];
u[6] = uvs[c2,tr,0];
u[7] = uvs[c2,tr,1];
u[8] = uvs[c2,tr,2];
return u;
}
}
And here’s what the texture looks like:



Well, without seeing the code that produces the coordinates it's hard to tell... The texture resolution might be different. Do you rely your calculations on a specific texture size? Do you use an atlas or any atlas tools? Packing textures into an atlas requires recalculation of the UVs. Again, without more information noone can answer this.
– Bunny83Right. I've added the code and the atlas (no tools required to make the Atlas - the UV coords are easy enough to work out manually). As I said though, it's working fine in the editor.
– quoxelI'd assume that the uv array that gets returned has random data in it. Maybe make some tests, perhaps get the color0, locked UVs and print out what's returned.
– Graham-DunnettHow can a method that's just fetching data from an array give random results? I'll do some testing as you suggest, but as it only happens on the device I am guessing it has to be some kind of issue with meshes created in code on the iPhone.
– quoxelcould someone help to figure out how to put this in script: void FixedUpdate() { while rigidbody2D is in motion continue that motion unless rigidbody 2D hits something then transform that motion into bounced direction }
– Toonda_Byood