| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 | using UnityEngine;using UnityEditor;using UnityEngine.UI;using System.Collections.Generic;using System.IO;using System.Linq;public class FindSelectedPrefabImages : EditorWindow{    private string targetFolder = "D:/FB/XiuXianGame/美术/art_use_ui/all"; // 指定外部图片目录(可修改)    private Vector2 scrollPosition;    [MenuItem("Tools/查找选中预制件中的Sprite图片名称")]    public static void ShowWindow()    {        // 显示编辑器窗口        GetWindow<FindSelectedPrefabImages>("查找Sprite图片名称");    }    void OnGUI()    {        GUILayout.Label("查找选中预制件中的Sprite图片名称(包括隐藏和所有深层子节点)并删除不匹配的图片", EditorStyles.boldLabel);        // 输入外部目标文件夹路径        GUILayout.Label("外部图片文件夹路径(例如 D:/Images):");        targetFolder = EditorGUILayout.TextField(targetFolder);        if (GUILayout.Button("查找Sprite图片名称并删除不匹配图片"))        {            DeleteNonMatchingImages();        }                            if (GUILayout.Button("开始替换"))        {            ReplaceImagesInPrefabs(targetFolder);        }    }    private void ReplaceImagesInPrefabs(string path)    {        string[] guids = AssetDatabase.FindAssets("t:Prefab", new[] { path });        foreach (string guid in guids)        {            string assetPath = AssetDatabase.GUIDToAssetPath(guid);            GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);            if (prefab == null) continue;            GameObject instance = (GameObject)PrefabUtility.InstantiatePrefab(prefab);            bool changed = false;            MyImage[] images = instance.GetComponentsInChildren<MyImage>(true);            foreach (var img in images)            {                img.UseGradient = false;                changed = true;            }            if (changed)            {                PrefabUtility.SaveAsPrefabAsset(instance, assetPath);                Debug.Log($"更新了预制件:{assetPath}");            }            DestroyImmediate(instance);        }        AssetDatabase.Refresh();        Debug.Log("替换完成!");    }    private void GetName(GameObject obj, HashSet<string> spriteFileNames)    {        // 查找该对象及其所有子对象(包括深层子节点)的Image组件,包括非活跃的        MyImage img = obj.GetComponent<MyImage>();        if (img != null)        {            // 获取Sprite的资源路径            // string spritePath = AssetDatabase.GetAssetPath(img.sprite);            if (!string.IsNullOrEmpty(img.icon_name) && img.icon_name != "")            {                spriteFileNames.Add(img.icon_name);            }        }        List<Transform> images = obj.GetComponentsInChildren<Transform>(true)?.ToList();        if (images != null && images.Count > 0)        {            images.Remove(obj.transform);            foreach (var myImage in images)            {                // if (myImage.sprite != null)                {                    GetName(myImage.gameObject, spriteFileNames);                }            }        }    }    private void DeleteNonMatchingImages()    {        // 获取当前选中的对象        GameObject[] selectedObjects = Selection.gameObjects;        if (selectedObjects.Length == 0)        {            Debug.LogWarning("没有选中任何对象!");            return;        }        // 存储Sprite图片的文件名(不含扩展名,忽略大小写)        HashSet<string> spriteFileNames = new HashSet<string>(System.StringComparer.OrdinalIgnoreCase);        // 查找所有引用的Sprite        foreach (GameObject obj in selectedObjects)        {            // 检查是否为预制件            if (PrefabUtility.IsPartOfAnyPrefab(obj))            {                GetName(obj, spriteFileNames);                // 查找该对象及其所有子对象(包括深层子节点)的Image组件,包括非活跃的                // MyImage[] images = obj.GetComponentsInChildren<MyImage>(true);                // foreach (MyImage img in images)                // {                //     if (img.sprite != null)                //     {                //         // 获取Sprite的资源路径                //         string spritePath = AssetDatabase.GetAssetPath(img.sprite);                //         if (!string.IsNullOrEmpty(spritePath))                //         {                //             // 提取文件名(不含扩展名)                //             string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(spritePath);                //             spriteFileNames.Add(fileNameWithoutExtension);                //             // 记录GameObject的层级路径、深度和活跃状态                //             string hierarchyPath = GetGameObjectPath(img.gameObject);                //             int depth = GetHierarchyDepth(img.gameObject);                //             bool isActive = img.gameObject.activeInHierarchy;                //             Debug.Log($"找到Sprite: {img.gameObject.name}, 文件名: {fileNameWithoutExtension}, 路径: {spritePath}, 层级: {hierarchyPath}, 层级深度: {depth}, 活跃状态: {(isActive ? "显示" : "隐藏")}");                //         }                //     }                // }            }        }        if (spriteFileNames.Count == 0)        {            Debug.LogWarning("选中的预制件中没有找到任何Sprite图片。");            return;        }        // 输出所有找到的Sprite文件名        Debug.Log($"找到的Sprite图片文件名: {string.Join(", ", spriteFileNames)}");        // 检查外部目标文件夹是否存在        if (!Directory.Exists(targetFolder))        {            Debug.LogError($"外部目标文件夹 {targetFolder} 不存在!");            return;        }        // 获取目标文件夹中的所有图片文件        string[] imageExtensions = { "*.png", "*.jpg", "*.jpeg", "*.tga" };        List<string> allImageFiles = new List<string>();        foreach (string ext in imageExtensions)        {            allImageFiles.AddRange(Directory.GetFiles(targetFolder, ext, SearchOption.AllDirectories)                .Select(path => path.Replace("\\", "/"))); // 统一路径分隔符        }        // 找出需要删除的图片(文件名不匹配Sprite文件名)        List<string> filesToDelete = allImageFiles            .Where(file =>            {                string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);                return !spriteFileNames.Contains(fileNameWithoutExtension);            })            .ToList();        if (filesToDelete.Count == 0)        {            Debug.Log("外部目录中没有需要删除的图片文件(所有图片文件名均匹配Sprite文件名)。");            return;        }        // 确认删除        if (EditorUtility.DisplayDialog("确认删除",                $"将要删除 {filesToDelete.Count} 个文件名不匹配Sprite图片的图片文件,是否继续?", "确定", "取消"))        {            int deletedCount = 0;            foreach (string file in filesToDelete)            {                try                {                    File.Delete(file);                    Debug.Log($"已删除图片: {file}");                    deletedCount++;                }                catch (System.Exception e)                {                    Debug.LogError($"删除图片失败: {file}, 错误: {e.Message}");                }            }            Debug.Log($"删除完成,共删除 {deletedCount} 个图片文件。");        }        else        {            Debug.Log("取消删除操作。");        }    }    // 获取GameObject的层级路径(用于显示递归层级)    private string GetGameObjectPath(GameObject obj)    {        string path = obj.name;        while (obj.transform.parent != null)        {            obj = obj.transform.parent.gameObject;            path = obj.name + "/" + path;        }        return path;    }    // 计算GameObject的层级深度(根节点为0)    private int GetHierarchyDepth(GameObject obj)    {        int depth = 0;        while (obj.transform.parent != null)        {            obj = obj.transform.parent.gameObject;            depth++;        }        return depth;    }}
 |