using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Threading;
using UnityEngine.SceneManagement;
using System;
using UnityEngine.UI;
/// <summary>
/// 查找圖片引用
/// </summary>
public class FindImageQuote : EditorWindow
{
Sprite targetImage;
string targetTag;
Vector2 scrollPos = new Vector2(0, 0);
bool cancel = false;
GameObject selectTargetGameObject;
GameObject hightLightTarget;
Dictionary<GameObject, GameObject> FindDictionary = new Dictionary<GameObject, GameObject>();
Dictionary<GameObject, bool> ToggleList = new Dictionary<GameObject, bool>();
[MenuItem("自定義工具/查找圖片引用")]
static void Init()
{
FindImageQuote myWindow = (FindImageQuote)EditorWindow.GetWindow(typeof(FindImageQuote), false, "查找圖片引用");//創建窗口
myWindow.Show();//展示
}
void Awake()
{
}
void Start()
{
//Debug.LogError("開始");
}
//獲取場景上存在的所有用戶自定義的prefab實例
List<GameObject> GetRealPreafabList()
{
List<GameObject> realPreafabList = new List<GameObject>();
//獲取當前激活的場景.
Scene scene = SceneManager.GetActiveScene();
//獲取場景上所有父級的GameObject.
var objs = scene.GetRootGameObjects();
foreach (var obj in objs)
{
if (PrefabUtility.GetPrefabType(obj) == PrefabType.PrefabInstance)
{
//找到了直接添加到表裏,不再繼續通過該節點深入查找
realPreafabList.Add(obj);
}
else
{
Queue<GameObject> queue = new Queue<GameObject>();
queue.Enqueue(obj);
while (queue.Count > 0)
{
bool is_add = false;
var new_obj = queue.Dequeue();
if (PrefabUtility.GetPrefabType(new_obj) == PrefabType.PrefabInstance)
{
realPreafabList.Add(new_obj);
is_add = true;
}
if (!is_add)
{
for (int i = 0; i < new_obj.transform.childCount; ++i)
{
var child = new_obj.transform.GetChild(i);
queue.Enqueue(child.gameObject);
}
}
}
}
}
//Debug.LogError(realPreafabList.Count);
return realPreafabList;
}
void OnGUI()
{
EditorGUILayout.Space();
targetImage = EditorGUILayout.ObjectField("添加圖片:", targetImage, typeof(Sprite), true) as Sprite;
#region 忽略列表
#endregion
#region 生成tag列表
//targetTag = EditorGUILayout.TagField("1111", targetTag);
#endregion
#region 生成自定義下拉菜單列表
//index = EditorGUILayout.Popup("菜單列表:", index, popupList);
#endregion
#region 打開通知的方法
//GUILayout.Space(20);
//if (GUILayout.Button("打開通知"))
//{
// this.ShowNotification(new GUIContent("This is a Notification"));
//}
//if (GUILayout.Button("關閉通知"))
//{
// this.RemoveNotification();
//}
#endregion
#region 文本框顯示鼠標在窗口的位置
//EditorGUILayout.LabelField("鼠標在窗口的位置", Event.current.mousePosition.ToString());
#endregion
GUILayout.Space(20);
EditorGUILayout.BeginHorizontal();
#region 批量查找
if (GUILayout.Button("開始查找"))
{
if (targetImage == null)
{
this.ShowNotification(new GUIContent("請放入圖片!!!!"));
//StartTimers();
}
else
{
FindDictionary.Clear();
this.Repaint();
FindAllQuote();
}
}
#endregion
EditorGUILayout.EndHorizontal();
#region 查找結果
if (FindDictionary != null && FindDictionary.Count > 0)
{
int times = 0;
GUILayout.Space(20);
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
foreach (var dic in FindDictionary)
{
string str = dic.Value.name;
if (dic.Key != dic.Value)
{
str = str + " 的 " + dic.Key.name;
}
#region 點擊對應的標籤後觸發
var editorStyle = EditorStyles.helpBox;
if (hightLightTarget != null && hightLightTarget == dic.Key)
{
editorStyle = EditorStyles.objectFieldThumb;
//str = str + " (當前選擇!!!!!)";
}
if (GUILayout.Button(str, editorStyle, GUILayout.Height(20f)))
{
var realPreafabList = GetRealPreafabList();
selectTargetGameObject = null;
hightLightTarget = null;
#region 查找場景中符合的prefab
foreach (var realPrefab in realPreafabList)
{
//獲取場景上這個prefab在project中的原始prefab
var target = PrefabUtility.GetPrefabParent(realPrefab);
if (target != null && target == dic.Value)
{
var target_obj = dic.Key;
string path = target_obj.name;
Transform newTransForm = target_obj.transform;
while (newTransForm.parent != null && newTransForm.parent.parent != null)
{
//獲取這個節點在prefab上的路徑(不包括root節點)
newTransForm = newTransForm.parent;
path = string.Format("{0}/{1}", newTransForm.name, path);
}
if (path != target_obj.name || newTransForm.parent != null)
{
selectTargetGameObject = realPrefab.transform.Find(path).gameObject;
}
else
{
selectTargetGameObject = realPrefab;
}
break;
}
}
#endregion
if (selectTargetGameObject == null)
{
//直接獲取資源目錄中的prefab
selectTargetGameObject = dic.Value;
}
//根據Object指引對應的位置
EditorGUIUtility.PingObject(selectTargetGameObject);
Selection.activeObject = selectTargetGameObject;
hightLightTarget = dic.Key;
}
#endregion
GUILayout.Space(10);
times++;
}
EditorGUILayout.EndScrollView();
}
#endregion
}
void FindAllQuote()
{
var assets = AssetDatabase.FindAssets("t:prefab", new string[] { "Assets/Game/UIs/Views" });
int startIndex = 0;
int max_length = assets.Length;
for (int i = startIndex; i < max_length; i++)
{
var guid = assets[i];
var path = AssetDatabase.GUIDToAssetPath(guid);
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
if (prefab != null)
{
var components = prefab.transform.GetComponentsInChildren(typeof(Image), true);
foreach (var component in components)
{
var img = component as Image;
if (img.sprite == targetImage)
{
FindDictionary.Add(component.gameObject, prefab.gameObject);
}
}
}
else
{
Debug.LogError("未知錯誤,無法找到prefab");
}
cancel = EditorUtility.DisplayCancelableProgressBar("匹配資源中", path, (float)i / (float)max_length);
if (cancel)
{
break;
}
}
EditorUtility.ClearProgressBar();
this.Repaint();
}
void StartTimers()
{
var threadTimer = new Timer(new TimerCallback((object value) => {Debug.LogError("!!!!!!!!!!!!!!"); this.RemoveNotification(); }), null, Timeout.Infinite, 1000);
threadTimer.Change(0, 1000);
//UnityEditor.EditorGUIUtility.PingObject
//AssetDatabase.GetAssetPath(object:GetIn)
//UnityEditor.PrefabUtility.GetPrefabParent
//UnityEditor.PrefabUtility.GetPrefabObject()
//Scene scene;
//var objs = scene.GetRootGameObjects();
}
void OnInspectorUpdate()
{
//Debug.LogError("面板實時刷新");
}
void OnProjectChange()
{
//Debug.LogError("當Project視圖中的資源發生改變時調用一次");
}
void OnFocus()
{
//Debug.LogError("當窗口獲得焦點時調用一次");
}
void OnLostFocus()
{
//Debug.LogError("當窗口丟失焦點時調用一次");
}
void OnHierarchyChange()
{
//Debug.LogError("當Hierarchy視圖中的任何對象發生改變時調用一次");
}
}