using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Threading;
using UnityEngine.SceneManagement;
using System;
/// <summary>
/// 查找組件,用於批量修改組件的操作
/// </summary>
public class FindComponent : EditorWindow
{
MonoScript targetScript;
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()
{
FindComponent myWindow = (FindComponent)EditorWindow.GetWindow(typeof(FindComponent), false, "查找組件引用");//創建窗口
myWindow.Show();//展示
}
void Awake()
{
//ulong a = 1;
//ulong b = 1;
//for (int i = 3; i <= 100; i++)
//{
// b = a + b;
// a = b - a;
// Debug.LogError(b);
//}
//Debug.LogError("加載");
}
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();
targetScript = EditorGUILayout.ObjectField("添加組件:", targetScript, typeof(MonoScript), true) as MonoScript;
#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 (targetScript == null)
{
this.ShowNotification(new GUIContent("請放入組件!!!!"));
//StartTimers();
}
else
{
FindDictionary.Clear();
this.Repaint();
FindAllQuote();
}
}
#endregion
#region 批量刪除
if (GUILayout.Button("批量刪除"))
{
if (targetScript == null)
{
this.ShowNotification(new GUIContent("請放入組件!!!!"));
}
else
{
AllDelete();
}
}
#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", "Assets/Game/Actors", "Assets/Game/Effects" });
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(targetScript.GetClass(), true);
foreach (var component in components)
{
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 AllDelete()
{
var assets = AssetDatabase.FindAssets("t:prefab", new string[] { "Assets/Game/UIs", "Assets/Game/Actors", "Assets/Game/Effects" });
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(targetScript.GetClass(), true);
foreach (var component in components)
{
FindDictionary.Remove(component.gameObject);
DestroyImmediate(component, true);
}
}
else
{
Debug.LogError("未知錯誤,無法找到prefab");
}
cancel = EditorUtility.DisplayCancelableProgressBar("匹配資源中", path, i / (max_length * 1.0f));
if (cancel)
{
break;
}
}
EditorUtility.ClearProgressBar();
AssetDatabase.SaveAssets();
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視圖中的任何對象發生改變時調用一次");
}
}