I have an array of Sprite objects in Unity. Their size vary depending on the image loaded. I want to combine them side by side like a tiled map into one image. I want them to be layout like your are forming a line of images, one after the other. (note: NOT one on top of the other) How may I be able to do this?
The reason why I'm combining (just for those who want to know) is because I'm using a polygon2D Collider. Since there are some weird behaviors happening when I use multiple colliders side by side, I decided to just combine the images before adding one big polygon collider. Note that these things happen during runtime. I can't just create a big image and load that because the order of the images is only determined at runtime.
I hope to receive some help with this. Thanks.
There is PackTextures method in Texture2D class, but since it makes your atlas square you can't make a line of sprites, so there is another way to do it by reading pixels of images and setting them to new image,it's really expensive to do in runtime but gives you the result.
// your textures to combine
// !! after importing as sprite change to advance mode and enable read and write property !!
public Sprite[] textures;
// just to see on editor nothing to add from editor
public Texture2D atlas;
public Material testMaterial;
public SpriteRenderer testSpriteRenderer;
int textureWidthCounter = 0;
int width,height;
void Start () {
// determine your size from sprites
width = 0;
height = 0;
foreach(Sprite t in textures)
{
width += t.texture.width;
// determine the height
if(t.texture.height > height)height = t.texture.height;
}
// make your new texture
atlas = new Texture2D(width,height,TextureFormat.RGBA32,false);
// loop through your textures
for(int i= 0; i<textures.Length; i++)
{
int y = 0;
while (y < atlas.height) {
int x = 0;
while (x < textures[i].texture.width ){
if(y < textures[i].texture.height){
// fill your texture
atlas.SetPixel(x + textureWidthCounter, y, textures[i].texture.GetPixel(x,y));
}
else {
// add transparency
atlas.SetPixel(x + textureWidthCounter, y,new Color(0f,0f,0f,0f));
}
++x;
}
++y;
}
atlas.Apply();
textureWidthCounter += textures[i].texture.width;
}
// for normal renderers
if(testMaterial != null)testMaterial.mainTexture = atlas;
// for sprite renderer just make a sprite from texture
Sprite s = Sprite.Create(atlas,new Rect(0f,0f,atlas.width,atlas.height),new Vector2(0.5f, 0.5f));
testSpriteRenderer.sprite = s;
// add your polygon collider
testSpriteRenderer.gameObject.AddComponent<PolygonCollider2D>();
}