Unity SpriteAtlas packaging preview window
Here we need to make a tool to confirm the utilization rate of the atlas to determine the rationality of the atlas.
Here is a utilization confirmation and simple drawing of a single atlas.
This is useless. If necessary, make it a batch confirmation tool. This is just a demonstration.
About Texture2D.PackTextures()
Texture2D.PackTextures() This is the packing function defined in Texture2D . At first I thought this was the packing function of the atlas.
But then I tried it for me, and it wasn't...
We add the following script,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.U2D;
using UnityEditor.U2D;
using System;
public class SpriteAtlasWindowOld : EditorWindow
{
static SpriteAtlasWindowOld window;
SpriteAtlas spriteAtlas;
Sprite[] sprites;
Texture2D[] texture2Ds;
Texture2D previewTexture;
readonly GUIStyle preBackground = "preBackground";
[MenuItem("Assets/GUI/Sprite preview old")]
static void Init()
{
window = GetWindow<SpriteAtlasWindowOld>("Spriteatlas Preview 01");
window.spriteAtlas = Selection.activeObject as SpriteAtlas;
window.sprites = new Sprite[window.spriteAtlas.spriteCount];
window.spriteAtlas.GetSprites(window.sprites);
window.texture2Ds = new Texture2D[window.sprites.Length];
for (int i = 0; i < window.sprites.Length; i++)
{
window.texture2Ds[i] = window.sprites[i].texture;
TextureImporter textureImporter = TextureImporter.GetAtPath(AssetDatabase.GetAssetPath(window.texture2Ds[i])) as TextureImporter;
textureImporter.isReadable = true;
textureImporter.SaveAndReimport();
}
SpriteAtlasPackingSettings packingsetting = SpriteAtlasExtensions.GetPackingSettings(window.spriteAtlas);
TextureImporterPlatformSettings platformsetting = SpriteAtlasExtensions.GetPlatformSettings(window.spriteAtlas, "Android");
window.previewTexture = new Texture2D(platformsetting.maxTextureSize, platformsetting.maxTextureSize);
window.previewTexture.PackTextures(window.texture2Ds, packingsetting.padding);
}
[MenuItem("Assets/GUI/Sprite preview old", true)]
static bool Valid()
{
if (Selection.activeObject.GetType() == typeof(SpriteAtlas))
return true;
else
return false;
}
private void OnGUI()
{
if (previewTexture != null)
{
Rect r = new Rect();
r.width = previewTexture.width;
r.height = previewTexture.height;
if (Event.current.type == EventType.Repaint)
preBackground.Draw(r, false, false, false, false);
EditorGUI.DrawTextureTransparent(r, previewTexture);
GUI.DrawTexture(r, previewTexture);
}
}
private void OnDisable()
{
window = null;
}
}
Open the window and take a look
Take a look at the gallery preview below,
. . . . Obviously, this is different, so we can't use this function in Texture2D.
About the Pack Preview button
Since we can't use the packaging function in Texture2D, let's take a look at how the Pack preview in the source code operates.
We can directly search for Pack Preview globally in the Unity editor source code and find what we want.
and then find where to use it,
We can see that the blue box is where it is used. Then let’s take a look at how to implement this function
. . . . That's it? ?
Since we won’t show you this part, let’s find another way.
Start with the preview window of the gallery
Since we cannot directly obtain the packaging result from the packaging preview, we can indirectly see where the texture drawn by the Inspector comes from.
We can see through InspectorWindow.cs that there is a PreviewWindow class, and we start with this class. Sure enough, we find the drawing function.
Next, let's start with Editor.cs and see what this DrawPreview() looks like.
We can see that it applies another static,
This static state is divided into the situation of drawing multiple and the situation of drawing single.
We can see that another layer of OnInteractivePreviewGUI has been adjusted in DrawPreview , and OnPreviewGUI() is executed inside to perform specific preview drawing. The exciting time has come, let’s see how it gets the package preview.
Finally, we found this function.
Go to this function and take a look.
This class is not a built-in class, but this function is, so we have to use reflection.
We write a static class to hold this function.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Reflection;
using UnityEngine.U2D;
using UnityEditor.U2D;
public static class ReflSpriteatlasExtensions
{
public static Texture2D[] GetPreviewTextures(SpriteAtlas spriteAtlas)
{
MethodInfo methodInfo = typeof(SpriteAtlasExtensions).GetMethod("GetPreviewTextures", BindingFlags.NonPublic | BindingFlags.Static);
if (methodInfo == null)
{
Debug.LogError("<color=red> 从 SpriteAtlasExtensions 获取方法为空! </color>");
return null;
}
else
{
return methodInfo.Invoke(null, new SpriteAtlas[] {
spriteAtlas }) as Texture2D[];
}
}
}
Once everything is ready, next, you need to write a window to draw the preview image.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.U2D;
using UnityEditor.U2D;
using System;
public class SpritePreviewWindow : EditorWindow
{
static SpritePreviewWindow window;
SpriteAtlas spriteAtlas;
Texture2D[] previewTextures;
readonly GUIStyle preBackground = "preBackground";
[MenuItem("Assets/GUI/Sprite preview 01")]
static void Init()
{
window = GetWindow<SpritePreviewWindow>("Spriteatlas Preview 01");
window.spriteAtlas = Selection.activeObject as SpriteAtlas;
SpriteAtlasUtility.PackAtlases(new SpriteAtlas[] {
window.spriteAtlas }, BuildTarget.Android);
//反射拿预览图集图片
window.previewTextures = ReflSpriteatlasExtensions.GetPreviewTextures(window.spriteAtlas);
}
[MenuItem("Assets/GUI/Sprite preview 01", true)]
static bool Valid()
{
if (Selection.activeObject.GetType() == typeof(SpriteAtlas))
return true;
else
return false;
}
private void OnGUI()
{
if (previewTextures != null && previewTextures.Length > 0 && previewTextures[0] != null)
{
Rect r = new Rect();
r.width = previewTextures[0].width;
r.height = previewTextures[0].height;
if (Event.current.type == EventType.Repaint)
preBackground.Draw(r, false, false, false, false);
EditorGUI.DrawTextureTransparent(r, previewTextures[0]);
GUI.DrawTexture(r, previewTextures[0]);
}
}
private void OnDisable()
{
window = null;
}
}
Although I don't know why they are missing a corner, but it doesn't matter, it doesn't matter, the important thing is that they are the same.
Perfect.