This code:
Vector2[] uvs = new Vector2[newMesh.vertices.Length];
for (int i = 0; i < uvs.Length; i++) {
uvs [i] = new Vector2 (newMesh.vertices [i].x, newMesh.vertices [i].y);
}
newMesh.uv = uvs;
Is equivalent to this:
Vector2[] uvs = new Vector2[6];
uvs[0] = new Vector2(0,0);
uvs[1] = new Vector2(1,0);
uvs[2] = new Vector2(0,-1);
uvs[3] = new Vector2(1,-1);
uvs[4] = new Vector2(0,0);
uvs[5] = new Vector2(0,-1);
newMesh.uv = uvs;
The UV coordinates for the square on the left are (0,0), (0,-1), (0,0), (0,-1). So it's a 0-pixel wide vertical strip along the left and the right borders of the texture. Interpolation is yielding avg(red,blue) => (purple) and avg(green,yellow) => (greenish-yellow).
Try this instead:
Vector2[] uvs = new Vector2[6];
uvs[0] = new Vector2(0,0);
uvs[1] = new Vector2(1,0);
uvs[2] = new Vector2(0,-1);
uvs[3] = new Vector2(1,-1);
uvs[4] = new Vector2(-1,0);
uvs[5] = new Vector2(-1,-1);
newMesh.uv = uvs;
Your confusion is because you are associating UV coordinates with world location. Don't do that. Use the vertex index instead. For example, order the vertices in your triangle strip like this:
0 - 2 - 4 - 6 - 8
| / | / | / | / |
1 - 3 - 5 - 7 - 9
Set UV coordinates of vertex i to (i / 2, i % 2)
.
Set triangles to (0,1,2),(1,2,3),(2,3,4),(3,4,5),...
If you want to make a tube that wraps around, just make sure to make the last two triangles reference the first two vertices, like so:
0 - 2 - 4 - 6 - 0
| / | / | / | / |
1 - 3 - 5 - 7 - 1