| using System;  | 
| using System.Collections.Generic;  | 
| using System.IO;  | 
| using System.Linq;  | 
| using System.Reflection;  | 
| using System.Text;  | 
| using System.Text.RegularExpressions;  | 
|   | 
| using UnityEditor;  | 
| using UnityEngine;  | 
| using UnityEngine.UI;  | 
|   | 
| public class SpriteManageTool : EditorWindow  | 
| {  | 
|     enum SpriteManageType  | 
|     {  | 
|         Reference,  | 
|     }  | 
|   | 
|     private Vector2 m_ScrollPosition;  | 
|     private Texture2D m_DeleteTexture;  | 
|     private List<IconConfig> m_IconCfgs;  | 
|   | 
|     [SerializeField]  | 
|     SpriteManageType m_SpriteManageType;  | 
|   | 
|     private static readonly Regex Directory_Regex = new Regex(@"/([0-9a-zA-Z_]+)$");  | 
|     private static readonly Regex Name_Regex = new Regex(@"\\([0-9a-zA-Z_\.]+)");  | 
|   | 
|     private static bool m_FindReference = false;  | 
|   | 
|     #region 风格  | 
|     private GUIStyle m_ButtonStyle;  | 
|   | 
|     private void InitStyle()  | 
|     {  | 
|         m_ButtonStyle = new GUIStyle();  | 
|     }  | 
|     #endregion  | 
|   | 
|   | 
|     [MenuItem("Assets/查找引用")]  | 
|     private static void FindReference()  | 
|     {  | 
|         m_FindReference = true;  | 
|         SpriteManageTool _window = GetWindow(typeof(SpriteManageTool), false, "查找资源") as SpriteManageTool;  | 
|         _window.Show();  | 
|         _window.autoRepaintOnSceneChange = true;  | 
|     }  | 
|   | 
|     // [MenuItem("Assets/查找引用", true)]  | 
|     // private static bool FindReferenceValid()  | 
|     // {  | 
|     //     string _path = AssetDatabase.GetAssetPath(Selection.activeObject);  | 
|     //     return (!string.IsNullOrEmpty(_path));  | 
|     // }  | 
|   | 
|     private void OnGUI()  | 
|     {  | 
|         GUI.skin.button.normal.textColor = Color.white;  | 
|   | 
|         DisplayFuncToggle();  | 
|   | 
|         UnityEngine.Object[] _objectArray = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets);  | 
|         var _selectPath = (_objectArray == null || _objectArray.Length == 0) ? string.Empty : Application.dataPath.Substring(0, Application.dataPath.LastIndexOf('/')) + "/" + AssetDatabase.GetAssetPath(_objectArray[0]);  | 
|         if (!ToolsHelper.lockFolderPath)  | 
|         {  | 
|             ToolsHelper.folderPath = _selectPath;  | 
|         }  | 
|   | 
|         GUI.skin.button.normal.textColor = Color.gray;  | 
|   | 
|         switch (m_SpriteManageType)  | 
|         {  | 
|             case SpriteManageType.Reference:  | 
|                 DisplayReference();  | 
|                 break;  | 
|         }  | 
|     }  | 
|   | 
|     private void OnEnable()  | 
|     {  | 
|         InitStyle();  | 
|   | 
|         m_SpriteManageType = SpriteManageType.Reference;  | 
|         if (m_FindReference)  | 
|         {  | 
|             m_ReferenceSource = Selection.activeObject;  | 
|         }  | 
|     }  | 
|   | 
|     private void DisplayFuncToggle()  | 
|     {  | 
|         GUILayout.BeginHorizontal();  | 
|         string[] labels = new string[1] { "查找引用" };  | 
|         m_SpriteManageType = (SpriteManageType)GUILayout.Toolbar((int)m_SpriteManageType, labels, "LargeButton", GUILayout.Width(labels.Length * 130));  | 
|         GUILayout.FlexibleSpace();  | 
|         GUILayout.EndHorizontal();  | 
|     }  | 
|   | 
|   | 
|   | 
|     #region 引用资源  | 
|     private UnityEngine.Object m_ReferenceSource;  | 
|     private UnityEngine.Object m_ReferenceReplace;  | 
|     private static string[] m_ReferenceDisplays = new string[] { "Material", "Prefab", "Asset", "Scene" };  | 
|     private Dictionary<UnityEngine.Object, string> m_ReferenceObjectDict = new Dictionary<UnityEngine.Object, string>();  | 
|     private Dictionary<UnityEngine.Object, bool> m_ReferenceReplaceDict = new Dictionary<UnityEngine.Object, bool>();  | 
|     private Dictionary<UnityEngine.Object, List<RefDetail>> m_ReferenceDetailDict = new Dictionary<UnityEngine.Object, List<RefDetail>>();  | 
|     private List<RefDetail> m_PrefabDetails = new List<RefDetail>();  | 
|     private string m_ReferenceGUID = string.Empty;  | 
|     [SerializeField] bool m_GlobalSearch = false;  | 
|     [SerializeField] int m_ReferenceType = 1 << (int)ReferenceType.Prefab;  | 
|     public enum ReferenceType  | 
|     {  | 
|         Material,  | 
|         Prefab,  | 
|         Asset,  | 
|         Scene,  | 
|     }  | 
|   | 
|     private void DisplayReference()  | 
|     {  | 
|         GUILayout.BeginHorizontal();  | 
|         GUILayout.Label("被引用的资源");  | 
|         m_ReferenceSource = EditorGUILayout.ObjectField(m_ReferenceSource, typeof(UnityEngine.Object), false);  | 
|         m_GlobalSearch = GUILayout.Toggle(m_GlobalSearch, "全局搜索");  | 
|         if (m_ReferenceSource != null && GUILayout.Button("显示GUID"))  | 
|         {  | 
|             m_ReferenceGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_ReferenceSource));  | 
|         }  | 
|         if (m_ReferenceSource != null && m_ReferenceSource is GameObject && GUILayout.Button("分析Prefab"))  | 
|         {  | 
|             m_PrefabDetails.Clear();  | 
|             GetReferenceDetail(File.ReadAllText(AssetDatabase.GetAssetPath(m_ReferenceSource)), string.Empty, m_PrefabDetails);  | 
|         }  | 
|         GUILayout.FlexibleSpace();  | 
|         GUILayout.EndHorizontal();  | 
|   | 
|         GUILayout.BeginHorizontal();  | 
|         GUILayout.Label("GUID:");  | 
|         EditorGUILayout.TextField(m_ReferenceGUID);  | 
|         GUILayout.FlexibleSpace();  | 
|         GUILayout.EndHorizontal();  | 
|   | 
|         if (m_ReferenceSource != null && m_ReferenceSource is GameObject)  | 
|         {  | 
|             DisplayPrefabDetail();  | 
|             return;  | 
|         }  | 
|   | 
|         if (!m_GlobalSearch)  | 
|         {  | 
|             ToolsHelper.DisplayFolderPath();  | 
|         }  | 
|         GUILayout.BeginHorizontal();  | 
|         GUILayout.Label("引用资源的类型");  | 
|         m_ReferenceType = EditorGUILayout.MaskField((int)m_ReferenceType, m_ReferenceDisplays);  | 
|         GUILayout.FlexibleSpace();  | 
|         GUILayout.EndHorizontal();  | 
|   | 
|         if (m_ReferenceSource != null && m_ReferenceSource is Texture2D)  | 
|         {  | 
|             GUILayout.BeginHorizontal();  | 
|             GUILayout.Label("替换资源");  | 
|             m_ReferenceReplace = EditorGUILayout.ObjectField(m_ReferenceReplace, typeof(UnityEngine.Object), false);  | 
|             if (!(m_ReferenceReplace is Texture2D))  | 
|             {  | 
|                 m_ReferenceReplace = null;  | 
|             }  | 
|             if (m_ReferenceObjectDict.Count > 0 && m_ReferenceReplace != null)  | 
|             {  | 
|                 if (GUILayout.Button("一键替换"))  | 
|                 {  | 
|                     var _replaceGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_ReferenceReplace));  | 
|                     m_ReferenceGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_ReferenceSource));  | 
|                     foreach (var _object in m_ReferenceReplaceDict.Keys)  | 
|                     {  | 
|                         if (m_ReferenceReplaceDict[_object] && m_ReferenceObjectDict.ContainsKey(_object))  | 
|                         {  | 
|                             var _allText = m_ReferenceObjectDict[_object];  | 
|                             var _path = AssetDatabase.GetAssetPath(_object);  | 
|                             if (Regex.IsMatch(_allText, m_ReferenceGUID))  | 
|                             {  | 
|                                 string _file = Regex.Replace(_allText, m_ReferenceGUID, _replaceGuid);  | 
|                                 File.WriteAllText(_path, _file);  | 
|                                 AssetDatabase.SaveAssets();  | 
|                                 AssetDatabase.Refresh();  | 
|                             }  | 
|                             m_ReferenceObjectDict.Remove(_object);  | 
|                         }  | 
|                     }  | 
|                 }  | 
|             }  | 
|             GUILayout.FlexibleSpace();  | 
|             GUILayout.EndHorizontal();  | 
|         }  | 
|   | 
|         if (GUILayout.Button("查找"))  | 
|         {  | 
|             if (m_ReferenceSource == null)  | 
|             {  | 
|                 Debug.LogError("未指定所引用的资源");  | 
|                 return;  | 
|             }  | 
|             if (!m_GlobalSearch && Regex.IsMatch(ToolsHelper.folderPath, @".*\..*"))  | 
|             {  | 
|                 Debug.LogError("必须为文件夹路径");  | 
|                 return;  | 
|             }  | 
|             string _path = AssetDatabase.GetAssetPath(m_ReferenceSource);  | 
|             if (!string.IsNullOrEmpty(_path))  | 
|             {  | 
|                 string _guid = AssetDatabase.AssetPathToGUID(_path);  | 
|                 StartFindReference(_guid);  | 
|             }  | 
|         }  | 
|   | 
|         m_ScrollPosition = GUILayout.BeginScrollView(m_ScrollPosition);  | 
|         foreach (var _object in m_ReferenceObjectDict.Keys)  | 
|         {  | 
|             GUILayout.BeginHorizontal();  | 
|             EditorGUILayout.ObjectField(_object, typeof(UnityEngine.Object), false);  | 
|             if (_object is GameObject &&  | 
|                 GUILayout.Button("显示详细信息"))  | 
|             {  | 
|                 if (!m_ReferenceDetailDict.ContainsKey(_object))  | 
|                 {  | 
|                     List<RefDetail> _details = new List<RefDetail>();  | 
|                     GetReferenceDetail(m_ReferenceObjectDict[_object], AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_ReferenceSource)), _details);  | 
|                     m_ReferenceDetailDict.Add(_object, _details);  | 
|                 }  | 
|             }  | 
|             if (_object is GameObject)  | 
|             {  | 
|                 m_ReferenceReplaceDict[_object] = EditorGUILayout.Toggle(m_ReferenceReplaceDict[_object]);  | 
|             }  | 
|             GUILayout.FlexibleSpace();  | 
|             GUILayout.EndHorizontal();  | 
|             if (m_ReferenceDetailDict.ContainsKey(_object))  | 
|             {  | 
|                 var _list = m_ReferenceDetailDict[_object];  | 
|                 for (int i = 0; i < _list.Count; i++)  | 
|                 {  | 
|                     var _detail = _list[i];  | 
|                     var _fatherDetail = _detail.fatherDetail;  | 
|                     GUILayout.BeginHorizontal();  | 
|                     GUILayout.Label(StringUtility.Contact(i + 1, ".", "Path: "));  | 
|                     var _path = StringUtility.Contact(_detail.fatherDetail, _fatherDetail == string.Empty ? string.Empty : "/", _detail.name);  | 
|                     GUILayout.TextField(_path);  | 
|                     if (_fatherDetail != string.Empty && GUILayout.Button("Goto"))  | 
|                     {  | 
|                         var _go = GameObject.Find(_path);  | 
|                         if (_go != null)  | 
|                         {  | 
|                             Selection.activeGameObject = _go;  | 
|                         }  | 
|                     }  | 
|                     if (_fatherDetail == string.Empty && GUILayout.Button("FindFather"))  | 
|                     {  | 
|                         _detail.fatherDetail = GetFatherDetail(_detail.fatherId);  | 
|                     }  | 
|                     GUILayout.FlexibleSpace();  | 
|                     GUILayout.EndHorizontal();  | 
|                 }  | 
|             }  | 
|             GUILayout.Space(5);  | 
|         }  | 
|         GUILayout.EndScrollView();  | 
|     }  | 
|   | 
|     private void DisplayPrefabDetail()  | 
|     {  | 
|         if (m_PrefabDetails.Count > 0 && GUILayout.Button("一键转换"))  | 
|         {  | 
|             for (int i = 0; i < m_PrefabDetails.Count; i++)  | 
|             {  | 
|                 m_PrefabDetails[i].GuidToObjects();  | 
|             }  | 
|         }  | 
|         m_ScrollPosition = GUILayout.BeginScrollView(m_ScrollPosition);  | 
|         for (int i = 0; i < m_PrefabDetails.Count; i++)  | 
|         {  | 
|             var _detail = m_PrefabDetails[i];  | 
|             if (_detail.guids.Count == 0)  | 
|             {  | 
|                 continue;  | 
|             }  | 
|             GUILayout.BeginHorizontal();  | 
|             var _fatherDetail = _detail.fatherDetail;  | 
|             GUILayout.Label(StringUtility.Contact(i + 1, ".", "Path: "));  | 
|             var _path = StringUtility.Contact(_detail.fatherDetail, _fatherDetail == string.Empty ? string.Empty : "/", _detail.name);  | 
|             GUILayout.TextField(_path);  | 
|             if (_fatherDetail != string.Empty && GUILayout.Button("Goto"))  | 
|             {  | 
|                 var _go = GameObject.Find(_path);  | 
|                 if (_go != null)  | 
|                 {  | 
|                     Selection.activeGameObject = _go;  | 
|                 }  | 
|             }  | 
|             if (_fatherDetail == string.Empty && GUILayout.Button("FindFather"))  | 
|             {  | 
|                 _detail.fatherDetail = GetFatherDetail(_detail.fatherId);  | 
|             }  | 
|             GUILayout.FlexibleSpace();  | 
|             GUILayout.EndHorizontal();  | 
|             for (int k = 0; k < _detail.guids.Count; k++)  | 
|             {  | 
|                 var _guid = _detail.guids[k];  | 
|                 if (_detail.objectDict.ContainsKey(_guid))  | 
|                 {  | 
|                     EditorGUILayout.ObjectField(_detail.objectDict[_guid], typeof(UnityEngine.Object), false);  | 
|                     continue;  | 
|                 }  | 
|                 GUILayout.BeginHorizontal();  | 
|                 GUILayout.Label("Guid:");  | 
|                 GUILayout.Label(_guid);  | 
|                 if (GUILayout.Button("GUID To 资源"))  | 
|                 {  | 
|                     if (!_detail.GuidToObject(k))  | 
|                     {  | 
|                         k--;  | 
|                     }  | 
|                 }  | 
|                 GUILayout.FlexibleSpace();  | 
|                 GUILayout.EndHorizontal();  | 
|             }  | 
|             GUILayout.Space(10);  | 
|         }  | 
|         GUILayout.EndScrollView();  | 
|     }  | 
|   | 
|     private void StartFindReference(string _guid)  | 
|     {  | 
|         m_ReferenceObjectDict.Clear();  | 
|         m_ReferenceReplaceDict.Clear();  | 
|         m_ReferenceDetailDict.Clear();  | 
|         m_RefDetailDict.Clear();  | 
|         var _referenceExtentions = GetReferenceExtention();  | 
|         if (_referenceExtentions.Count == 0)  | 
|         {  | 
|             Debug.LogError("未指定任意一种引用资源类型");  | 
|             return;  | 
|         }  | 
|         string[] _files = Directory.GetFiles(m_GlobalSearch ? Application.dataPath : ToolsHelper.folderPath, "*.*", SearchOption.AllDirectories)  | 
|             .Where(s => _referenceExtentions.Contains(Path.GetExtension(s).ToLower())).ToArray();  | 
|         int _index = 0;  | 
|         if (_files == null || _files.Length == 0)  | 
|         {  | 
|             EditorUtility.DisplayDialog("提示", "未找到任意文件", "确定");  | 
|             return;  | 
|         }  | 
|         EditorApplication.update = delegate ()  | 
|         {  | 
|             string _file = _files[_index];  | 
|             bool isCancel = EditorUtility.DisplayCancelableProgressBar("查找引用资源", _file, (float)_index / (float)_files.Length);  | 
|             var _allTxt = File.ReadAllText(_file);  | 
|             if (Regex.IsMatch(_allTxt, _guid))  | 
|             {  | 
|                 UnityEngine.Object _object = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(GetRelativeAssetsPath(_file));  | 
|                 m_ReferenceObjectDict.Add(_object, _allTxt);  | 
|                 m_ReferenceReplaceDict.Add(_object, false);  | 
|             }  | 
|   | 
|             _index++;  | 
|             if (isCancel || _index >= _files.Length)  | 
|             {  | 
|                 EditorUtility.ClearProgressBar();  | 
|                 EditorApplication.update = null;  | 
|                 _index = 0;  | 
|             }  | 
|         };  | 
|     }  | 
|   | 
|     private List<string> GetReferenceExtention()  | 
|     {  | 
|         var _list = new List<string>();  | 
|         for (int i = 0; i < m_ReferenceDisplays.Length; i++)  | 
|         {  | 
|             if ((m_ReferenceType & (1 << i)) != 0)  | 
|             {  | 
|                 switch ((ReferenceType)i)  | 
|                 {  | 
|                     case ReferenceType.Material:  | 
|                         _list.Add(".mat");  | 
|                         break;  | 
|                     case ReferenceType.Prefab:  | 
|                         _list.Add(".prefab");  | 
|                         break;  | 
|                     case ReferenceType.Asset:  | 
|                         _list.Add(".asset");  | 
|                         break;  | 
|                     case ReferenceType.Scene:  | 
|                         _list.Add(".unity");  | 
|                         break;  | 
|                 }  | 
|             }  | 
|         }  | 
|         return _list;  | 
|     }  | 
|   | 
|     private readonly Regex s_PrefabRegex = new Regex(@"--- !u![0-9]+ \&([0-9]+)");  | 
|     private readonly Regex s_GameObjectRegex = new Regex(@"m_GameObject\: \{fileID\: ([0-9]+)\}");  | 
|     private readonly Regex s_GameObjectNameRegex = new Regex(@"m_Name\: ([a-zA-Z0-9_]+)");  | 
|     private readonly Regex s_GuidRegex = new Regex(@"guid\: ([a-z0-9]+)");  | 
|     private readonly Regex s_GameObjectFatherRegex = new Regex(@"m_Father\: \{fileID\: ([0-9]+)\}");  | 
|     private Dictionary<string, RefDetail> m_RefDetailDict = new Dictionary<string, RefDetail>();  | 
|   | 
|     private void GetReferenceDetail(string _data, string _guid, List<RefDetail> _details)  | 
|     {  | 
|         var _strArray = s_PrefabRegex.Split(_data);  | 
|         MatchCollection _matchs = s_PrefabRegex.Matches(_data);  | 
|         List<string> _list = new List<string>(_strArray);  | 
|         m_RefDetailDict.Clear();  | 
|         if (_strArray != null)  | 
|         {  | 
|             _list.RemoveAll((x) =>  | 
|             {  | 
|                 return Regex.IsMatch(x, "^[0-9]+$");  | 
|             });  | 
|             var _index = 1;  | 
|             EditorApplication.update = delegate ()  | 
|             {  | 
|                 var _match = _matchs[_index - 1];  | 
|                 GetRefComponent(_list[_index], _list[_index].Split('\n'), _match.Groups[1].Value);  | 
|                 bool isCancel = EditorUtility.DisplayCancelableProgressBar("查找引用资源",  | 
|                     StringUtility.Contact(_index, "/", _list.Count), (float)_index / (float)_list.Count);  | 
|                 _index++;  | 
|                 if (isCancel || _index >= _list.Count)  | 
|                 {  | 
|                     _index = 0;  | 
|                     if (_guid == string.Empty)  | 
|                     {  | 
|                         _details.AddRange(m_RefDetailDict.Values.ToList());  | 
|                         EditorUtility.ClearProgressBar();  | 
|                         EditorApplication.update = null;  | 
|                         System.GC.Collect();  | 
|                         return;  | 
|                     }  | 
|                     var _keys = m_RefDetailDict.Keys.ToList();  | 
|                     EditorApplication.update = delegate ()  | 
|                     {  | 
|                         var _detail = m_RefDetailDict[_keys[_index]];  | 
|                         if (_detail.guids.Contains(_guid))  | 
|                         {  | 
|                             _details.Add(_detail);  | 
|                         }  | 
|                         isCancel = EditorUtility.DisplayCancelableProgressBar("查找引用资源",  | 
|                             StringUtility.Contact(_index, "/", _keys.Count), (float)_index / (float)_keys.Count);  | 
|                         _index++;  | 
|                         if (isCancel || _index >= _keys.Count)  | 
|                         {  | 
|                             EditorUtility.ClearProgressBar();  | 
|                             _index = 0;  | 
|                             EditorApplication.update = null;  | 
|                             System.GC.Collect();  | 
|                         }  | 
|                     };  | 
|                 }  | 
|             };  | 
|         }  | 
|     }  | 
|   | 
|     private void GetRefComponent(string _source, string[] _msgs, string _fileId)  | 
|     {  | 
|         if (_msgs != null)  | 
|         {  | 
|             switch (_msgs[1])  | 
|             {  | 
|                 case "GameObject:":  | 
|                     {  | 
|                         RefDetail _detail = new RefDetail();  | 
|                         m_RefDetailDict.Add(_fileId, _detail);  | 
|                         var _match = s_GameObjectNameRegex.Match(_source);  | 
|                         _detail.name = _match != null ? _match.Groups[1].Value : string.Empty;  | 
|                         _detail.fileId = _fileId;  | 
|                     }  | 
|                     break;  | 
|                 case "MonoBehaviour:":  | 
|                     {  | 
|                         var _match = s_GameObjectRegex.Match(_source);  | 
|                         if (_match != null)  | 
|                         {  | 
|                             var _id = _match.Groups[1].Value;  | 
|                             var _refDetail = m_RefDetailDict.ContainsKey(_id) ? m_RefDetailDict[_id] : null;  | 
|                             if (_refDetail != null)  | 
|                             {  | 
|                                 var _guidMatchs = s_GuidRegex.Matches(_source);  | 
|                                 if (_guidMatchs != null)  | 
|                                 {  | 
|                                     foreach (Match _guidMatch in _guidMatchs)  | 
|                                     {  | 
|                                         _refDetail.guids.Add(_guidMatch.Groups[1].Value);  | 
|                                     }  | 
|                                 }  | 
|                             }  | 
|                         }  | 
|                     }  | 
|                     break;  | 
|                 case "RectTransform:":  | 
|                     {  | 
|                         var _match = s_GameObjectRegex.Match(_source);  | 
|                         if (_match != null)  | 
|                         {  | 
|                             var _id = _match.Groups[1].Value;  | 
|                             var _refDetail = m_RefDetailDict.ContainsKey(_id) ? m_RefDetailDict[_id] : null;  | 
|                             if (_refDetail != null)  | 
|                             {  | 
|                                 _refDetail.rectId = _fileId;  | 
|                                 var _fatherMatch = s_GameObjectFatherRegex.Match(_source);  | 
|                                 _refDetail.fatherId = _fatherMatch != null ? _fatherMatch.Groups[1].Value : string.Empty;  | 
|                             }  | 
|                         }  | 
|                     }  | 
|                     break;  | 
|             }  | 
|         }  | 
|     }  | 
|   | 
|     public class RefDetail  | 
|     {  | 
|         public string fileId = string.Empty;  | 
|         public string name = string.Empty;  | 
|         public string fatherId = string.Empty;  | 
|         public string rectId = string.Empty;  | 
|         public string fatherDetail = string.Empty;  | 
|         public List<string> guids = new List<string>();  | 
|         public Dictionary<string, UnityEngine.Object> objectDict = new Dictionary<string, UnityEngine.Object>();  | 
|   | 
|         public void GuidToObjects()  | 
|         {  | 
|             if (objectDict.Count >= guids.Count)  | 
|             {  | 
|                 return;  | 
|             }  | 
|             for (int i = 0; i < guids.Count; i++)  | 
|             {  | 
|                 if (objectDict.ContainsKey(guids[i]))  | 
|                 {  | 
|                     continue;  | 
|                 }  | 
|                 if (!GuidToObject(i))  | 
|                 {  | 
|                     i--;  | 
|                 }  | 
|             }  | 
|         }  | 
|   | 
|         public bool GuidToObject(int _index)  | 
|         {  | 
|             var _objectPath = AssetDatabase.GUIDToAssetPath(guids[_index]);  | 
|             var _object = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(_objectPath);  | 
|             if (_object == null || (_object != null && _object.name == "UnityEngine.UI"))  | 
|             {  | 
|                 guids.RemoveAt(_index);  | 
|                 return false;  | 
|             }  | 
|             else  | 
|             {  | 
|                 objectDict.Add(guids[_index], _object);  | 
|                 return true;  | 
|             }  | 
|         }  | 
|     }  | 
|   | 
|     public string GetFatherDetail(string _fatherId)  | 
|     {  | 
|         if (_fatherId == string.Empty)  | 
|         {  | 
|             return string.Empty;  | 
|         }  | 
|         foreach (var _detail in m_RefDetailDict.Values)  | 
|         {  | 
|             if (_detail.rectId == _fatherId)  | 
|             {  | 
|                 var _father = GetFatherDetail(_detail.fatherId);  | 
|                 return StringUtility.Contact(GetFatherDetail(_detail.fatherId), _father == string.Empty ? string.Empty : "/", _detail.name);  | 
|             }  | 
|         }  | 
|         return string.Empty;  | 
|     }  | 
|     #endregion  | 
|   | 
|   | 
|   | 
|     private string GetRelativeAssetsPath(string _path)  | 
|     {  | 
|         return "Assets" + Path.GetFullPath(_path).Replace(Path.GetFullPath(Application.dataPath), "").Replace('\\', '/');  | 
|     }  | 
|   | 
|     private string GetGUIDByAssets(UnityEngine.Object _object)  | 
|     {  | 
|         if (_object == null)  | 
|         {  | 
|             return string.Empty;  | 
|         }  | 
|         return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(_object));  | 
|     }  | 
|   | 
| }  | 
|   | 
|   | 
| public static class ToolsHelper  | 
| {  | 
|     [SerializeField] public static string folderPath = string.Empty;  | 
|     [SerializeField] public static bool lockFolderPath = false;  | 
|   | 
|     [SerializeField] public static string m_ExternalFilePath = string.Empty;  | 
|   | 
|     public static void DisplayFolderPath()  | 
|     {  | 
|         GUILayout.BeginHorizontal();  | 
|         GUILayout.Label("文件路径");  | 
|         folderPath = GUILayout.TextField(folderPath);  | 
|         lockFolderPath = GUILayout.Toggle(lockFolderPath, "Lock");  | 
|         GUILayout.FlexibleSpace();  | 
|         GUILayout.EndHorizontal();  | 
|     }  | 
|   | 
|     public static string GetRelativeAssetsPath(string _path)  | 
|     {  | 
|         return "Assets" + Path.GetFullPath(_path).Replace(Path.GetFullPath(Application.dataPath), "").Replace('\\', '/');  | 
|     }  | 
|   | 
|     public static string GetGUIDByAssets(UnityEngine.Object _object)  | 
|     {  | 
|         if (_object == null)  | 
|         {  | 
|             return string.Empty;  | 
|         }  | 
|         return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(_object));  | 
|     }  | 
|   | 
|     public static void DisplayExternalPath()  | 
|     {  | 
|         GUILayout.BeginHorizontal();  | 
|         GUILayout.Label(StringUtility.Contact("文件夹路径:", m_ExternalFilePath));  | 
|         if (GUILayout.Button("选择文件根路径"))  | 
|         {  | 
|             var _path = EditorUtility.OpenFolderPanel("根路径", "", "");  | 
|             m_ExternalFilePath = _path;  | 
|         }  | 
|         GUILayout.FlexibleSpace();  | 
|         GUILayout.EndHorizontal();  | 
|     }  | 
|   | 
|   | 
|     static string content = string.Empty;  | 
|     static Font fontData = null;  | 
|     static FontStyle fontStyle;  | 
|     static int fontSize = 14;  | 
|     static float lineSpacing = 0f;  | 
|     static bool richText = true;  | 
|     static TextAnchor alignment;  | 
|     static HorizontalWrapMode hwmode;  | 
|     static VerticalWrapMode vwmode;  | 
|     static Color m_Color;  | 
|     static Material m_Material;  | 
|     static bool raycastTarget;  | 
|   | 
|     public static TextEx PasteText(Text text)  | 
|     {  | 
|         content = text.text;  | 
|         fontData = text.font;  | 
|         fontStyle = text.fontStyle;  | 
|         fontSize = text.fontSize;  | 
|         lineSpacing = text.lineSpacing;  | 
|         richText = text.supportRichText;  | 
|         alignment = text.alignment;  | 
|         hwmode = text.horizontalOverflow;  | 
|         vwmode = text.verticalOverflow;  | 
|         m_Color = text.color;  | 
|         m_Material = text.material;  | 
|         raycastTarget = text.raycastTarget;  | 
|   | 
|         var gameObject = text.gameObject;  | 
|         Component.DestroyImmediate(text);  | 
|         TextEx textex = gameObject.AddMissingComponent<TextEx>();  | 
|   | 
|         textex.text = content;  | 
|         textex.font = fontData;  | 
|         textex.fontStyle = fontStyle;  | 
|         textex.fontSize = fontSize;  | 
|         textex.lineSpacing = lineSpacing;  | 
|         textex.supportRichText = richText;  | 
|         textex.alignment = alignment;  | 
|         textex.horizontalOverflow = hwmode;  | 
|         textex.verticalOverflow = vwmode;  | 
|         textex.color = m_Color;  | 
|         textex.material = m_Material;  | 
|         textex.raycastTarget = raycastTarget;  | 
|   | 
|         return textex;  | 
|     }  | 
| } |