Unity 指定文件夹图片自动设置为 Sprite

需求

在 Unity 项目中,UI 图片导入后通常需要手动设置:
Texture Type:Sprite (2D and UI) // 指定图片用于UI精灵渲染
Sprite Mode:Single // 整张图作为单个独立精灵
Mesh Type:Full Rect // 生成完整矩形渲染网格
关闭 Generate Mipmap // 不生成多级缩小贴图,避免UI模糊
开启 Alpha Is Transparency // 识别透明通道,去除边缘杂边

这个脚本可以将导入该文件夹中的图片一键设置,然后场景meta文件

使用步骤

  • 在项目中创建文件:
    Assets/Editor/AutoSpriteImporter.cs

  • 使用方法
    修改脚本中的文件夹配置:
    private static readonly string[] SpriteFolders =
    {
    "Assets/UI/Sprites",
    "Assets/UI/Icons",
    };
    当图片被拖入以下位置时:
    Assets/UI/Sprites/button.png
    Assets/UI/Sprites/Common/frame.png
    Assets/UI/Icons/gold.png
    Unity 会自动将它们设置为 Sprite。
    其他文件夹中的图片不会受到影响。

  • 排除特定图片
    如果某些图片不希望被自动处理,可以把它们放入名称包含 no_auto_process 的目录:
    Assets/UI/Sprites/no_auto_process/special_texture.png
    脚本检测到该关键字后会直接跳过。

~~点击查看代码~~
#if UNITY_EDITOR

using System;
using UnityEditor;
using UnityEngine;

/// <summary>
/// 指定文件夹图片自动设置为 Sprite。
///
/// 安装方式:
/// 1. 在你的 Unity 项目中创建 Assets/Editor 文件夹。
/// 2. 将本文件复制到 Assets/Editor/AutoSpriteImporter.cs。
/// 3. 修改下面的 SpriteFolders,填写需要自动处理的文件夹。
///
/// 生效范围:
/// - 新拖入配置文件夹的图片。
/// - 配置文件夹子目录中的图片。
/// - 被覆盖或重新导入的图片。
/// - 已经存在的图片和手动修改的设置不会被脚本覆盖。
///
/// 本工具仅使用 Unity 原生 Editor API,不依赖任何第三方插件。
 #region 功能如下
// 指定多个自动 Sprite 文件夹
// 自动设置 Sprite (2D and UI)
// 可选强制 Single
// 设置 Full Rect
// 关闭 Mipmap
// 开启 Alpha Is Transparency
// 支持 no_auto_process 路径排除
 #endregion
/// </summary>
public sealed class AutoSpriteImporter : AssetPostprocessor
{
    #region 可修改配置

    /// <summary>
    /// 需要自动设置为 Sprite 的文件夹。
    ///
    /// 填写规则:
    /// - 必须是 Unity 资源路径,以 "Assets/" 开头。
    /// - 不要填写电脑绝对路径,例如 D:/Project/Assets/UI。
    /// - 配置一个文件夹后,它的所有子文件夹也会生效。
    /// - 可以继续添加任意数量的文件夹。
    ///
    /// 示例:
    /// "Assets/UI/Sprites"
    /// 会处理:
    /// "Assets/UI/Sprites/button.png"
    /// "Assets/UI/Sprites/Icons/gold.png"
    /// </summary>
    private static readonly string[] SpriteFolders =
    {
        "Assets/UI/Sprites",

        // 需要更多目录时,取消注释或继续添加:
        // "Assets/UI/Icons",
        // "Assets/UI/Backgrounds",
    };

    /// <summary>
    /// 路径中包含这个名称时,跳过自动处理。
    ///
    /// 例如下面的图片不会被修改:
    /// Assets/UI/Sprites/no_auto_process/test.png
    ///
    /// 如果不需要排除机制,可以改成空字符串:
    /// private const string SkipPathKeyword = "";
    /// </summary>
    private const string SkipPathKeyword = "no_auto_process";

    /// <summary>
    /// Sprite 的 Pixels Per Unit。
    /// 对普通 UGUI 项目通常使用 Unity 默认值 100。
    /// </summary>
    private const float SpritePixelsPerUnit = 100f;

    /// <summary>
    /// 是否强制使用 Single 模式。
    ///
    /// true:
    /// 一张图片对应一个 Sprite,适合普通 UI 图片。
    ///
    /// false:
    /// 不修改 Sprite Mode,可保留手动设置的 Multiple 切图。
    /// </summary>
    private const bool ForceSingleSprite = true;

    /// <summary>
    /// 是否将 Sprite 网格设置为 Full Rect。
    ///
    /// Full Rect 使用完整矩形网格,通常更适合 UGUI Image、
    /// Mask、九宫格和需要精确 RectTransform 尺寸的界面。
    /// </summary>
    private const bool UseFullRectMesh = true;

    /// <summary>
    /// 是否关闭 Mipmap。
    ///
    /// 普通 UI 图片通常不需要 Mipmap。
    /// 如果这些图片还会作为远近变化明显的世界物体贴图使用,
    /// 可以将此项改为 false。
    /// </summary>
    private const bool DisableMipmaps = true;

    /// <summary>
    /// 是否开启 Alpha Is Transparency。
    ///
    /// 开启后,Unity 会把 Alpha 通道用于透明区域处理,
    /// 通常可以改善 PNG 图片透明边缘的表现。
    /// </summary>
    private const bool AlphaIsTransparency = true;

    #endregion

    /// <summary>
    /// Unity 在正式导入一张图片之前调用这个方法。
    ///
    /// assetPath:
    /// 当前正在导入的资源路径,例如:
    /// Assets/UI/Sprites/button.png
    ///
    /// assetImporter:
    /// 当前资源对应的导入器。图片资源对应 TextureImporter。
    ///
    /// 注意:
    /// 不要在 OnPreprocessTexture 中调用 SaveAndReimport,
    /// 因为当前图片本来就在导入过程中,再次导入可能造成循环。
    /// </summary>
    private void OnPreprocessTexture()
    {
        // 如果图片不在配置的目录中,就完全不修改它。
        if (!ShouldProcessAsset(assetPath))
        {
            return;
        }

        // importSettingsMissing 表示 Unity 没有找到这张图片已有的导入设置,
        // 一般意味着图片是第一次拖入项目,还没有可用的 .meta 配置。
        //
        // 已经存在的图片再次 Reimport,或者在 Inspector 修改后点击 Apply,
        // importSettingsMissing 通常是 false,因此这里直接退出,
        // 不会再把你的单独设置改回脚本中的默认值。
        //
        // 不是首次导入就直接退出。
        // 因此手动修改图片设置后点击 Apply,不会被本脚本重新覆盖。
        if (!assetImporter.importSettingsMissing)
        {
            return;
        }

        // 将通用 AssetImporter 转换成图片专用的 TextureImporter。
        TextureImporter textureImporter = assetImporter as TextureImporter;
        if (textureImporter == null)
        {
            return;
        }

        // 对应 Inspector 中的:
        // Texture Type = Sprite (2D and UI)
        textureImporter.textureType = TextureImporterType.Sprite;

        if (ForceSingleSprite)
        {
            // 对应 Inspector 中的:
            // Sprite Mode = Single
            textureImporter.spriteImportMode = SpriteImportMode.Single;
        }

        // 对应 Inspector 中的 Pixels Per Unit。
        textureImporter.spritePixelsPerUnit = SpritePixelsPerUnit;

        // UI 图片一般不需要 Mipmap。
        textureImporter.mipmapEnabled = !DisableMipmaps;

        // 处理带 Alpha 通道图片的透明边缘。
        textureImporter.alphaIsTransparency = AlphaIsTransparency;

        if (UseFullRectMesh)
        {
            // Mesh Type 不直接暴露在 TextureImporter 的普通属性中,
            // 因此需要先读取完整导入设置,再修改并写回。
            TextureImporterSettings settings = new TextureImporterSettings();

            // 读取图片已有设置,避免无意覆盖其他导入参数。
            textureImporter.ReadTextureSettings(settings);

            // 对应 Inspector 中的:
            // Mesh Type = Full Rect
            settings.spriteMeshType = SpriteMeshType.FullRect;

            // 将修改后的设置写回图片导入器。
            textureImporter.SetTextureSettings(settings);
        }
    }

    /// <summary>
    /// 判断一个资源是否需要自动处理。
    /// </summary>
    private static bool ShouldProcessAsset(string resourcePath)
    {
        if (string.IsNullOrWhiteSpace(resourcePath))
        {
            return false;
        }

        // Unity 的资源路径统一使用 "/"。
        // 做一次替换可以兼容手动配置时误写成 "\" 的情况。
        string normalizedResourcePath = NormalizePath(resourcePath);

        // 路径包含排除关键字时直接跳过。
        // OrdinalIgnoreCase 表示不区分英文大小写。
        if (!string.IsNullOrEmpty(SkipPathKeyword) &&
            normalizedResourcePath.IndexOf(
                SkipPathKeyword,
                StringComparison.OrdinalIgnoreCase) >= 0)
        {
            return false;
        }

        foreach (string configuredFolder in SpriteFolders)
        {
            if (string.IsNullOrWhiteSpace(configuredFolder))
            {
                continue;
            }

            // 去除目录末尾的斜杠,保证后面的比较格式统一。
            string normalizedFolder =
                NormalizePath(configuredFolder).TrimEnd('/');

            // 主动补上 "/",避免目录名称相似时发生误匹配。
            //
            // 例如配置 Assets/UI/Sprites:
            // 可以匹配 Assets/UI/Sprites/button.png
            // 不会误匹配 Assets/UI/SpritesBackup/button.png
            string folderPrefix = normalizedFolder + "/";

            if (normalizedResourcePath.StartsWith(
                    folderPrefix,
                    StringComparison.OrdinalIgnoreCase))
            {
                return true;
            }
        }

        return false;
    }

    /// <summary>
    /// 将路径中的反斜杠转换成 Unity 使用的正斜杠。
    /// </summary>
    private static string NormalizePath(string path)
    {
        return path.Replace('\\', '/');
    }
}

#endif


posted @ 2026-07-30 20:48  mdyyyds_blog  阅读(2)  评论(0)    收藏  举报