Hi,
I have a bunch of individual textures that I want (automatically) to copy into a bigger one by order to create a spritesheet (I need them in order, so i cant use Textures.Pack).
I initially wanted to use Graphics.CopyTexture, since it’s the one that lets me say in which specific part of the destination texture I want to copy each sprite (perfect for constructing a spritesheet).
However, I have found that CopyTexture only works on the GPU side, resulting in the sheet correctly showing on inspector:
But the image file is completely empty:
I think I can use Render Textures to then use Blit() after copying everything, but I’m not sure how, and I can’t find any docs.
Here is the code:
void GenerateSpritesheet()
{
string[] fileEntries = Directory.GetFiles(Application.dataPath + "/" + originPath, "*.png");
List<Texture> allFrames = new List<Texture>();
foreach (string fileName in fileEntries)
{
int index = fileName.LastIndexOf("/");
string localPath = "Assets/" + originPath;
if (index > 0)
localPath += fileName.Substring(index);
Texture t = (Texture)AssetDatabase.LoadAssetAtPath(localPath, typeof(Texture));
if (t != null)
allFrames.Add(t);
}
int size = Mathf.NextPowerOfTwo((int)Mathf.Sqrt((float)allFrames.Count)) * 512;
//First, store the texture empty to have a texture importer
Texture2D spritesheet = new Texture2D(size, size, TextureFormat.RGBA32, false);
Byte[] png = spritesheet.EncodeToPNG();
File.WriteAllBytes(Application.dataPath + "/" + spritesheetPath + animName + ".png", png);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
spritesheet = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/" + spritesheetPath + animName + ".png");
TextureImporter textureImporter = AssetImporter.GetAtPath("Assets/" + spritesheetPath + animName + ".png") as TextureImporter;
textureImporter.textureType = TextureImporterType.Sprite;
textureImporter.alphaIsTransparency = true;
textureImporter.filterMode = FilterMode.Point;
textureImporter.spriteImportMode = SpriteImportMode.Multiple;
textureImporter.maxTextureSize = 8192;
textureImporter.isReadable = true;
textureImporter.SaveAndReimport();
int x = 0;
int y = spritesheet.width;
foreach (Texture t in allFrames)
{
Graphics.CopyTexture(t, 0, 0, 0, 0, t.width, t.height, spritesheet, 0, 0, x, y - t.height);
x += t.width;
if (x >= spritesheet.width)
{
x = 0;
y -= t.height;
}
}
//spritesheet.Apply();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}