【Unity编辑器扩展】图片转Sprite工具、批处理材质文件

0. 由来

前段时间策划妹子跑过来提了个需求,说是Unity文件夹下图片太多,有些图片的Texture Type是Sprite(用于UI图集),有些是Default,鱼龙混杂的,单靠眼睛筛选根本管不过来,筛完手动改成Sprite更是人都麻了,于是有了这个工具

1. 批量修改图片格式

1.1 同步版

using UnityEngine;
using UnityEditor;
using System.IO;
using System.Linq;
using System.Text;

public class ChangePicType2Sprite : EditorWindow
{
    StringBuilder stringBuilder = new StringBuilder();
    static string inputFolder = "";

    [MenuItem("PicTools/ChangePicType2Sprite")]
    public static void ShowWindow()
    {
        EditorWindow.GetWindow(typeof(ChangePicType2Sprite));
    }

    void OnGUI()
    {
    	// 空格
        EditorGUILayout.Space(20);

		// 样式颜色
        GUIStyle style = new GUIStyle();
        style.normal.textColor = Color.red;
        style.fontSize = 20;
        
        EditorGUILayout.LabelField("注意:该工具只将目录下的png、jpg、jpeg三种图片格式改成Sprite! ", style);
        EditorGUILayout.Space(20);

        EditorGUILayout.LabelField("注意:图片名称, 文件夹名称不要包含123456(连续数字), 135246这样的可以", style);
        EditorGUILayout.Space(20);

        EditorGUILayout.LabelField("注意:禁止使用纯数字给图片或文件夹命名!", style);
        EditorGUILayout.Space(20);

        EditorGUILayout.LabelField("Input Folder : ", inputFolder);
        EditorGUILayout.Space(20);

        if (GUILayout.Button("Select"))
        {
            inputFolder = EditorUtility.OpenFolderPanel("Select Input Folder", "", "");
        }

        EditorGUILayout.Space(20);
        
        if (GUILayout.Button("Change"))
        {
            ChangeTextures();
        }
    }
    private void OnDestroy()
    {
        if (inputFolder != "")
        {
            inputFolder = "";
        }
    }

    void ChangeTextures()
    {
        string inputPath = inputFolder;
        stringBuilder.Clear();

		// 获取路径下所有文件路径
        GetAllPathFiles(inputPath);
        
        string[] files = stringBuilder.ToString().Split("123456"); // 这里以123456作了分割
        Debug.Log(files.Length);
        
        if (files.Length == 0)
        {
            EditorUtility.DisplayDialog("Failed", "Don't exist png or jpg file in selected filePath...", "OK");
            return;
        }

        foreach (string file in files)
        {
            string assetPath = GetPathFromAssets(file);
            TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
            if (importer != null && importer.textureType != TextureImporterType.Sprite)
            {
                importer.textureType = TextureImporterType.Sprite;
                importer.spriteImportMode = SpriteImportMode.Single;
                importer.spritePixelsPerUnit = 100;
                importer.filterMode = FilterMode.Bilinear;
                importer.textureCompression = TextureImporterCompression.Compressed;
                importer.SaveAndReimport();
            }
        }
        AssetDatabase.Refresh();
        EditorUtility.DisplayDialog("Success", "Picture type changed successfully.", "OK");
    }

	// // 递归的获取文件夹、子文件夹下所有图片文件(png、jpg、jpeg)
    private void GetAllPathFiles(string inputPath)
    {
        string[] files1 = Directory.GetFiles(inputPath, "*.png");
        string[] files2 = Directory.GetFiles(inputPath, "*.jpg");
        string[] files3 = Directory.GetFiles(inputPath, "*.jpeg");
        string[] files = files1.Concat(files2).Concat(files3).ToArray();
        foreach (var item in files)
        {
            stringBuilder.Append(item);
            stringBuilder.Append("123456");
        }
        // 获取子文件夹
        string[] subFolders = Directory.GetDirectories(inputPath);
        foreach (var item in subFolders)
        {
            GetAllPathFiles(item);
        }
    }

	// 根据文件路径获取特定路径(Assets开头)
    private string GetPathFromAssets(string inputPath)
    {
        int index = 0;
        string[] folderStr = inputPath.Split("/");
        for (int i = 0; i < folderStr.Length; i++)
        {
            if (folderStr[i] == "Assets")
            {
                index = i;
                break;
            }
        }
		StringBuilder sb = new StringBuilder();
		for (int i = index; i < folderStr.Length; i++)
		{
    		sb.Append(folderStr[i]);
    		sb.Append("/");
		}
		// 去除最后一个 / 并返回
		return sb.ToString().Substring(0, sb.Length - 1);
    }
}

优点:代码好理解,没用异步、Lambda表达式
缺点:卡线程,运行时间长

2.2 异步版

using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;

public class ChangePicType2Sprite : EditorWindow
{
    StringBuilder stringBuilder = new StringBuilder();
    static string inputFolder = "";

    [MenuItem("PicTools/ChangePicType2Sprite")]
    public static void ShowWindow()
    {
        EditorWindow.GetWindow(typeof(ChangePicType2Sprite));
    }

    void OnGUI()
    {
        EditorGUILayout.Space(20);

        GUIStyle style = new GUIStyle();
        style.normal.textColor = Color.red;
        style.fontSize = 20;
        EditorGUILayout.LabelField("注意:该工具只将目录下的png、jpg、jpeg三种图片格式改成Sprite! ", style);
        EditorGUILayout.Space(20);

        EditorGUILayout.LabelField("注意:图片名称, 文件夹名称不要包含123456(连续数字), 135246这样的可以", style);
        EditorGUILayout.Space(20);

        EditorGUILayout.LabelField("注意:禁止使用纯数字给图片或文件夹命名!", style);
        EditorGUILayout.Space(20);

        EditorGUILayout.LabelField("Input Folder : ", inputFolder);
        EditorGUILayout.Space(20);

        if (GUILayout.Button("Select"))
        {
            inputFolder = EditorUtility.OpenFolderPanel("Select Input Folder", "Assets\\GameResources\\Textures\\UI", "");
        }

        EditorGUILayout.Space(20);

        if (GUILayout.Button("Change"))
        {
            ChangeTextures();
        }
    }
    private void OnDestroy()
    {
        if (inputFolder != "")
        {
            inputFolder = "";
        }
    }

    async void ChangeTextures()
    {
        await Task.Run(() =>
        {
            string inputPath = inputFolder;
            stringBuilder.Clear();
            GetAllPathFiles(inputPath);
            string[] files = stringBuilder.ToString().Split("123456");
            Debug.Log(files.Length);
            if (files.Length == 0)
            {
                EditorUtility.DisplayDialog("Failed", "Don't exist png or jpg file in selected filePath...", "OK");
                return;
            }

            EditorApplication.delayCall += () =>
            {
                foreach (string file in files)
                {
                    string assetPath = GetPathFromAssets(file);
                    TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;

                    if (importer != null && importer.textureType != TextureImporterType.Sprite)
                    {
                        importer.textureType = TextureImporterType.Sprite;
                        importer.spriteImportMode = SpriteImportMode.Single;
                        importer.spritePixelsPerUnit = 100;
                        importer.filterMode = FilterMode.Bilinear;
                        importer.textureCompression = TextureImporterCompression.Compressed;
                        importer.SaveAndReimport();
                    }
                }
                AssetDatabase.Refresh();
                EditorUtility.DisplayDialog("Success", "Picture type changed successfully.", "OK");
            };
        });
    }
    private void GetAllPathFiles(string inputPath)
    {
        string[] files1 = Directory.GetFiles(inputPath, "*.png");
        string[] files2 = Directory.GetFiles(inputPath, "*.jpg");
        string[] files3 = Directory.GetFiles(inputPath, "*.jpeg");
        string[] files = files1.Concat(files2).Concat(files3).ToArray();
        foreach (var item in files)
        {
            stringBuilder.Append(item);
            stringBuilder.Append("123456");
        }
        string[] subFolders = Directory.GetDirectories(inputPath);
        foreach (var item in subFolders)
        {
            GetAllPathFiles(item);
        }
    }

    private string GetPathFromAssets(string inputPath)
    {
        int index = 0;
        string[] folderStr = inputPath.Split("/");
        for (int i = 0; i < folderStr.Length; i++)
        {
            if (folderStr[i] == "Assets")
            {
                index = i;
                break;
            }
        }
        StringBuilder sb = new StringBuilder();
        for (int i = index; i < folderStr.Length; i++)
        {
            sb.Append(folderStr[i]);
            sb.Append("/");
        }
        // 去除最后一个 / 并返回
        return sb.ToString().Substring(0, sb.Length - 1);
    }
}

优点:不卡线程,运行时间短
缺点:需要掌握Lambda表达式,异步等知识

2. 初始化材质文件参数默认值

我们在项目中可能会有修改材质参数值的需求
例如:

_mat.SetColor(ShaderProperty._part1Color, defaultColor);

由于美术在做模型或资源的时候,自己手动调试查看效果,最后上传了文件或者同一批材质没有初始默认值这一说,但到了程序通过代码操作的时候,可能会造成初始值很乱的现象,所以需要一个工具普照大地,一视同仁

using CoreAvatar.Config;
using CoreAvatar.Mgr;
using System.IO;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;

public class ModifyMatFiles : EditorWindow
{
    static string folderPath = ResourceConfigLoader.kRootPath + "/Arts/Suits"; // 替换为你指定的文件夹路径

    [MenuItem("PicTools/Init Mat Properties")] // 添加自定义菜单项方便执行脚本

    private async static void ModifyProperties()
    {
        await Task.Run(() =>
        {
            string[] matFiles = Directory.GetFiles(folderPath, "*.mat", SearchOption.AllDirectories);

            EditorApplication.delayCall += () =>
            {
                foreach (string matFile in matFiles)
                {
                    Material _mat = AssetDatabase.LoadAssetAtPath(matFile, typeof(Material)) as Material;

                    if (_mat != null)
                    {
                        
                        if (_mat.HasProperty(ShaderProperty._part1Color))
                        {
                            _mat.SetColor(ShaderProperty._part1Color, Color.black);
                        }
                        // 可能还有很多参数, 这里不举例了
                        // ...
                        // ...
                        // ...
                        // ...

                        EditorUtility.SetDirty(_mat); // 标记资源为"脏",以便保存修改
                    }
                }
                AssetDatabase.SaveAssets(); // 保存修改的资源
                AssetDatabase.Refresh(); // 刷新资源面板
                EditorUtility.DisplayDialog("Tips", "Init Mat Successfully !!!", "ok");
            };
        });

    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Unity C#脚本,用于将获取网络图片换为Sprite的过程封装成一个方法: ```c# using UnityEngine; using System.Collections; using System.Net; public class ImageDownloader : MonoBehaviour { public void DownloadImage(string url, System.Action<Sprite> onComplete) { StartCoroutine(DownloadImageCoroutine(url, onComplete)); } IEnumerator DownloadImageCoroutine(string url, System.Action<Sprite> onComplete) { using (WWW www = new WWW(url)) { yield return www; if (www.error != null) { Debug.LogError("Failed to download image: " + www.error); onComplete(null); yield break; } Texture2D texture = www.texture; Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero); onComplete(sprite); } } } ``` 这个脚本有一个名为`DownloadImage`的公共方法,用于获取网络图片换为Sprite。这个方法有两个参数:要获取的图片的URL和一个`Action<Sprite>`类型的回调函数,用于在获取和换完成后将结果返回给调用方。 在这个方法中,我们首先启动一个协程来获取网络图片。在协程中,我们使用WWW类从网络中获取图片,然后将获取到的Texture2D对象用于创建Sprite对象。如果获取或换过程中出现错误,我们将调用回调函数并将Sprite对象设置为null。如果获取和换都成功完成了,我们将调用回调函数并将获取到的Sprite对象作为参数传递给它。 你可以将这个脚本添加到一个GameObject上,然后在需要获取网络图片换为Sprite的地方,使用以下代码调用: ```c# ImageDownloader imageDownloader = GetComponent<ImageDownloader>(); imageDownloader.DownloadImage("https://example.com/image.png", OnImageDownloaded); void OnImageDownloaded(Sprite sprite) { // 在这里使用获取到的sprite,比如将它设置为一个UI Image的Sprite等 } ``` 在这个示例代码中,我们首先获取ImageDownloader组件,然后调用DownloadImage方法来获取网络图片换为Sprite。在回调函数OnImageDownloaded中,我们可以使用获取到的Sprite对象进行后续的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值