When I go to:
Window > 2D > Sprite Packer
I can preview atlas textures generated automatically by Sprite Packer. What I would like to do is to save all of them into PNG files so I can look them up outside Unity editor.
I wrote following script that was supposed to do so:
using UnityEngine;
using UnityEditor;
using UnityEditor.Sprites;
using System.Collections;
using System.IO;
public class AtlasTextureExporter : MonoBehaviour
{
[MenuItem("Tools/Atlas Exporter/Export atlases as PNG")]
static void ExportAtlases()
{
string[] atlasNames = Packer.atlasNames;
for (int i = 0; i < atlasNames.Length; i++)
{
string atlasName = atlasNames*;*
for (int j = 0; j < textures.Length; j++) { Texture2D texture = textures[j]; if (!Directory.Exists(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) + “/Atlases”)) Directory.CreateDirectory(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) + “/Atlases”); FileStream fs = new FileStream(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) + “/Atlases/” + texture.name + “.png”, FileMode.Create); BinaryWriter bw = new BinaryWriter(fs); bw.Write(texture.EncodeToPNG()); bw.Close(); fs.Close(); } } } } But I get following error: > ArgumentException: Texture > ‘SpriteAtlasTexture-myScene-2048x2048-fmt12’ > is not readable, the texture memory > can not be accessed from scripts. You > can make the texture readable in the > Texture Import Settings. > AtlasTextureExporter.ExportAtlases () > (at > Assets/Root/Editor/AtlasTextureExporter.cs:27) How can I make an atlas texture readable? If I cannot, how can I save an atlas texture into a PNG file?
Same issue here with the new SpriteAtlas system. I had to copy the texture to a new RenderTexture first then save the copy, solution from here.
I couldn’t find a direct way to access the SpriteAtlas texture so I went through the internal method Unity uses to show it in the inspector panel. Obviously not using this for production, but here is how I save a SpriteAtlas to a PNG:
[MenuItem("Tools/Export atlases as PNG")]
static void ExportAtlases() {
string exportPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/Atlases";
foreach (UnityEngine.Object obj in Selection.objects) {
SpriteAtlas atlas = (SpriteAtlas) obj;
if (atlas == null) continue;
Debug.Log("Exporting selected atlas: " + atlas);
// use reflection to run this internal editor method
// UnityEditor.U2D.SpriteAtlasExtensions.GetPreviewTextures
// internal static extern Texture2D[] GetPreviewTextures(this SpriteAtlas spriteAtlas);
Type type = typeof(UnityEditor.U2D.SpriteAtlasExtensions);
MethodInfo methodInfo = type.GetMethod("GetPreviewTextures", BindingFlags.Static | BindingFlags.NonPublic);
if (methodInfo == null) {
Debug.LogWarning("Failed to get UnityEditor.U2D.SpriteAtlasExtensions");
return;
}
Texture2D[] textures = (Texture2D[])methodInfo.Invoke(null, new object[] {atlas} );
if (textures == null) {
Debug.LogWarning("Failed to get texture results");
continue;
}
foreach (Texture2D texture in textures) {
// these textures in memory are not saveable so copy them to a RenderTexture first
Texture2D textureCopy = DuplicateTexture(texture);
if (!Directory.Exists(exportPath)) Directory.CreateDirectory(exportPath);
string filename = exportPath + "/" + texture.name + ".png";
FileStream fs = new FileStream(filename, FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(textureCopy.EncodeToPNG());
bw.Close();
fs.Close();
Debug.Log("Saved texture to " + filename);
}
}
}
private static Texture2D DuplicateTexture(Texture2D source) {
RenderTexture renderTex = RenderTexture.GetTemporary(
source.width,
source.height,
0,
RenderTextureFormat.Default,
RenderTextureReadWrite.Linear);
Graphics.Blit(source, renderTex);
RenderTexture previous = RenderTexture.active;
RenderTexture.active = renderTex;
Texture2D readableText = new Texture2D(source.width, source.height);
readableText.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
readableText.Apply();
RenderTexture.active = previous;
RenderTexture.ReleaseTemporary(renderTex);
return readableText;
}