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()

Insert image description here

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

Insert image description here
Take a look at the gallery preview below,

Insert image description here
. . . . 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.

Insert image description here

and then find where to use it,

Insert image description here
We can see that the blue box is where it is used. Then let’s take a look at how to implement this function

Insert image description here
. . . . 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.

Insert image description here
Next, let's start with Editor.cs and see what this DrawPreview() looks like.

We can see that it applies another static,

Insert image description here
This static state is divided into the situation of drawing multiple and the situation of drawing single.

Insert image description here
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.
Insert image description here
Insert image description here

Insert image description here

Finally, we found this function.

Insert image description here

Go to this function and take a look.

Insert image description here
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.

Insert image description here

Perfect.

Guess you like

Origin blog.csdn.net/weixin_44293055/article/details/120473824