Unity编辑器拓展之二十八:Sprite Border自动设置工具

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_26999509/article/details/99470879

Unity编辑器拓展之二十八:Sprite Border自动设置工具

1.0 功能介绍

自动计算出九宫格Sprite 的border数据并直接赋值保存的工具。【纯属偷懒,可能各位觉得没啥用吧,哈哈】

当需要为一个九宫格Sprite 设置Border数据时,需要打开Sprite Editor,然后输入Border数据。

工具会直接计算横向、纵向连续完全相同的列数、行数(当然连续区域取最大的),当计算出的九宫区域满足条件时(我设定的条件是连续列数或者行数有个最小值设定),就任务该图可以处理为九宫格Sprite。

以上九宫格Sprite,又称为 点九图【废话】。

2.0 源码

脚本放置在Editor文件夹下

using System.IO;
using UnityEditor;
using UnityEngine;

public class SpriteImporterTool : UnityEditor.Editor
{
    public static int continuousColNum = 10; //continuousColNum:连续的列数,大于等于这个值判定为横向可以九宫处理
    public static int continuousRowNum = 10; //continuousRowNum:连续的行数,大于等于这个值判定为纵向可以九宫处理
    
    //自动计算Sprite Border数据
    [MenuItem("Assets/SpriteBorder/AutoSetSpriteBorder", false, 500)]
    public static void AutoSetSpriteBorder()
    {
        foreach (var spriteAsset in Selection.objects)
        {
            AutoSetSpriteBorder(AssetDatabase.GetAssetPath(spriteAsset));
        }
    }

 	//设置Sprite Border为Zero
    [MenuItem("Assets/SpriteBorder/Reset Zero", false)]
    public static void AutoSetSpriteBorderZero()
    {
        foreach (var spriteAsset in Selection.objects)
        {
            SetSpriteBorder(AssetDatabase.GetAssetPath(spriteAsset), Vector4.zero);
        }
    }

    private static void AutoSetSpriteBorder(string spriteAssetPath)
    {
        TextureImporter textureImporter = AssetImporter.GetAtPath(spriteAssetPath) as TextureImporter;
        if (textureImporter != null && textureImporter.textureType == TextureImporterType.Sprite)
        {
            Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(spriteAssetPath);

            Vector4 border = Vector4.zero;
            GetBorderSliceInfo(sprite.texture, continuousColNum, continuousRowNum, ref border);

            if (border != Vector4.zero)
            {
                textureImporter.spriteBorder = border;
                EditorUtility.SetDirty(sprite);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }
        }
    }

    private static void SetSpriteBorder(string spriteAssetPath, Vector4 border)
    {
        TextureImporter textureImporter = AssetImporter.GetAtPath(spriteAssetPath) as TextureImporter;
        if (textureImporter != null && textureImporter.textureType == TextureImporterType.Sprite)
        {
            Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(spriteAssetPath);

            textureImporter.spriteBorder = border;
            EditorUtility.SetDirty(sprite);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
    }

    public static void GetBorderSliceInfo(Texture2D texture, int continuousColNum, int continuousRowNum,
        ref Vector4 border)
    {
        int width = texture.width;
        int height = texture.height;

        //咳咳,这里的命名规则请忽略,从另一个python工具拷贝过来
        int cur_begin_col_index = 0;
        int cur_end_col_index = 0;
        int slice_begin_col_index = 0;
        int slice_end_col_index = 0;

        Texture2D readTexture2D = GetReadTexture2D(texture);
        for (int col = 0; col < width - 1; col++)
        {
            if (EqualColPixel(readTexture2D, col, col + 1) == false)
            {
                if ((cur_begin_col_index != cur_end_col_index) &&
                    (cur_end_col_index - cur_begin_col_index >= continuousColNum) &&
                    (cur_end_col_index - cur_begin_col_index > slice_end_col_index - slice_begin_col_index))
                {
                    slice_begin_col_index = cur_begin_col_index;
                    slice_end_col_index = cur_end_col_index;
                }

                cur_begin_col_index = col + 1;
                cur_end_col_index = col + 1;
            }
            else
            {
                cur_end_col_index = col + 1;
            }
        }

        int cur_begin_row_index = 0;
        int cur_end_row_index = 0;
        int slice_begin_row_index = 0;
        int slice_end_row_index = 0;

        for (int row = 0; row < height - 1; row++)
        {
            if (EqualRowPixel(readTexture2D, row, row + 1) == false)
            {
                if ((cur_begin_row_index != cur_end_row_index) &&
                    (cur_end_row_index - cur_begin_row_index >= continuousRowNum) &&
                    (cur_end_row_index - cur_begin_row_index > slice_end_row_index - slice_begin_row_index))
                {
                    slice_begin_row_index = cur_begin_row_index;
                    slice_end_row_index = cur_end_row_index;
                }

                cur_begin_row_index = row + 1;
                cur_end_row_index = row + 1;
            }
            else
            {
                cur_end_row_index = row + 1;
            }
        }

        if (slice_end_col_index - slice_begin_col_index < continuousColNum)
        {
            slice_begin_col_index = 0;
            slice_end_col_index = width - 1;
        }

        if (slice_end_row_index - slice_begin_row_index < continuousRowNum)
        {
            slice_begin_row_index = 0;
            slice_end_row_index = height - 1;
        }

        //LTRB
        //row 是纵向的  T B
        //col 是横向的  L R
        border = new Vector4(slice_begin_col_index, slice_begin_row_index, width - slice_end_col_index - 1,
            height - slice_end_row_index - 1);
    }

    public static string GetAssetFullPath(UnityEngine.Object asset)
    {
        return System.Environment.CurrentDirectory + Path.DirectorySeparatorChar +
               AssetDatabase.GetAssetPath(asset);
    }

    public static Texture2D GetReadTexture2D(Texture texture)
    {
        string textureFilePath = GetAssetFullPath(texture);
        FileStream fileStream = new FileStream(textureFilePath, FileMode.Open, FileAccess.Read);
        fileStream.Seek(0, SeekOrigin.Begin);
        byte[] bytes = new byte[fileStream.Length];
        fileStream.Read(bytes, 0, (int) fileStream.Length);
        fileStream.Close();
        fileStream.Dispose();
        Texture2D new_texture = new Texture2D(texture.width, texture.height);
        new_texture.LoadImage(bytes);
        return new_texture;
    }

    /// <summary>
    /// 比较两行像素是否完全相等
    /// </summary>
    /// <param name="texture">isReadable为true,可读的texture</param>
    /// <param name="row1"></param>
    /// <param name="row2"></param>
    /// <returns></returns>
    public static bool EqualRowPixel(Texture2D texture, int row1, int row2)
    {
        Color[] row1Colors = texture.GetPixels(0, row1, texture.width, 1);
        Color[] row2Colors = texture.GetPixels(0, row2, texture.width, 1);
        for (int i = 0; i < row1Colors.Length; i++)
        {
            if (!row1Colors[i].Equals(row2Colors[i]))
            {
                return false;
            }
        }

        return true;
    }

    /// <summary>
    /// 比较两列像素是否完全相等
    /// </summary>
    /// <param name="texture">isReadable为true,可读的texture</param>
    /// <param name="col1"></param>
    /// <param name="col2"></param>
    /// <returns></returns>
    public static bool EqualColPixel(Texture2D texture, int col1, int col2)
    {
        Color[] col1Colors = texture.GetPixels(col1, 0, 1, texture.height);
        Color[] col2Colors = texture.GetPixels(col2, 0, 1, texture.height);
        for (int i = 0; i < col1Colors.Length; i++)
        {
            if (!col1Colors[i].Equals(col2Colors[i]))
            {
                return false;
            }
        }

        return true;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_26999509/article/details/99470879
今日推荐