查找选中物体的引用脚本
这个插件非常适合看别人项目时,为了理清逻辑关系,有时候需要在Hierarchy面板上一个一个找,看那个物体身上的脚本引用了你想要找的物体。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using UnityEngine.SceneManagement;
namespace MyUtility
{
public class FindObjRefsEditorWindow : EditorWindow
{
#region window
[MenuItem("Tools/MyUtility/FindObjRefs")]
static void Open()
{
OpenWindow("FindObjRefs");
}
Vector2 scrollPos;
public static void OpenWindow(string windowTitle)
{
FindObjRefsEditorWindow window = GetWindow<FindObjRefsEditorWindow>(windowTitle);
window.position = new Rect(Screen.width / 2, Screen.height / 2, 500, 500);
window.Show();
}
protected void Button(string btnName, Action action = null, float width = 300)
{
if (GUILayout.Button(btnName, GUILayout.Width(width)))
{
if (action != null)
action();
}
}
protected void Button(string btnName, Action action = null)
{
if (GUILayout.Button(btnName))
{
EditorApplication.delayCall += () =>
{
if (action != null)
action();
};
}
}
protected void ShowNotification(string msg)
{
this.ShowNotification(new GUIContent(msg));
}
/// <summary>
/// 在这里实现自己的编辑器界面。
/// </summary>
protected virtual void OnGUI()
{
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
DrawFindRefWindowGUI();
EditorGUILayout.EndScrollView();
}
protected virtual void OnEnable()
{
}
protected virtual void OnFocus()
{
}
/// <summary>
/// 只要选择发生改变时调用。
/// </summary>
protected virtual void OnSelectionChange()
{
//Transform tr = Selection.transforms[0];
//Debug.Log("当前选择的是:" + tr.name);
}
/// <summary>
/// 在给定检视面板每秒10帧更新。
/// </summary>
protected virtual void OnInspectorUpdate()
{
//Debug.Log("窗口面板的更新");
//这里开启窗口的重绘,不然窗口信息不会刷新
this.Repaint();
}
#endregion
#region FindObjRefs
List<MonoBehaviour> references = new List<MonoBehaviour>();
List<string> fieldNames = new List<string>();
Transform preTran = null;
bool checkRef(object obj)
{
bool b = false;
Transform s = Selection.activeTransform;
if (s == null) return b;
List<Component> c = new List<Component>();
c.Clear();
List<Transform> transforms = new List<Transform>();
transforms.Clear();
transforms.Add(s.transform);
int len = transforms.Count;
for (int i = 0; i < len; i++)
{
Transform t = transforms[i];
if (t == null) continue;
Component[] components = t.GetComponents<Component>();
if (components.Length > 0)
{
c.AddRange(components);
}
}
int l = c.Count;
for (int j = 0; j < l; j++)
{
Component com = c[j];
if (com == null) continue;
if ((object)com == obj || (object)com.gameObject == obj)
{
b = true;
break;
}
}
return b;
}
public static void GetChildrenTrans(Transform transform, List<Transform> transforms)
{
int l = transform.childCount;
if (l <= 0) return;
for (int i = 0; i < l; i++)
{
var child = transform.GetChild(i);
if (child != null)
{
transforms.Add(child);
GetChildrenTrans(child, transforms);
}
}
}
public static List<Transform> GetActiveSceneTrans()
{
List<Transform> trans = new List<Transform>();
GameObject[] roots = getSceneRootGameObjects(GetCurrentActiveScene());
int len = roots.Length;
for (int i = 0; i < len; i++)
{
GameObject g = roots[i];
if (g == null) continue;
trans.Add(g.transform);
GetChildrenTrans(g.transform, trans);
}
//Debug.Log(trans.Count);
return trans;
}
public static GameObject[] getSceneRootGameObjects(Scene scene)
{
return scene.GetRootGameObjects();
}
public static Scene GetCurrentActiveScene()
{
return SceneManager.GetActiveScene();
}
void find_reference()
{
references.Clear();
fieldNames.Clear();
List<MonoBehaviour> monos = new List<MonoBehaviour>();
monos.Clear();
List<Transform> trans = GetActiveSceneTrans();
int len = trans.Count;
for (int i = 0; i < len; i++)
{
Transform tran = trans[i];
if (tran == null) continue;
MonoBehaviour[] mono = tran.GetComponents<MonoBehaviour>();
if (mono.Length > 0)
{
monos.AddRange(mono);
}
}
Transform select = Selection.activeTransform;
if (select == null) return;
preTran = select;
int l = monos.Count;
for (int i = 0; i < l; i++)
{
MonoBehaviour mono = monos[i];
if (mono == null) continue;
System.Reflection.FieldInfo[] fieldInfos = mono.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
int fieldLen = fieldInfos.Length;
for (int j = 0; j < fieldLen; j++)
{
System.Reflection.FieldInfo fieldInfo = fieldInfos[j];
if (fieldInfo == null) continue;
if (checkRef(fieldInfo.GetValue(mono)))
{
//Debug.Log("Find");
references.Add(mono);
fieldNames.Add(fieldInfo.Name);
}
if (fieldInfo.GetValue(mono) != null
&& fieldInfo.GetValue(mono).GetType() != null)
{
System.Reflection.FieldInfo[] fields = fieldInfo.GetValue(mono).GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
int _len = fields.Length;
for (int k = 0; k < _len; k++)
{
System.Reflection.FieldInfo f = fields[k];
if (f == null) continue;
if (checkRef(f.GetValue(fieldInfo.GetValue(mono))))
{
//Debug.Log("Find");
references.Add(mono);
fieldNames.Add(fieldInfo.Name + "/" + f.Name);
}
}
}
}
}
}
void reference_GUI()
{
if (fieldNames.Count <= 0) return;
references.RemoveAll(r => r == null);
int len = references.Count;
for (int i = 0; i < len; i++)
{
MonoBehaviour mono = references[i];
string fieldName = fieldNames[i];
if (mono == null) continue;
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.LabelField("FieldName: <" + fieldName + ">", EditorStyles.boldLabel);
EditorGUILayout.ObjectField(mono, typeof(MonoBehaviour), true);
if (GUILayout.Button("Find"))
{
EditorApplication.delayCall += () =>
{
Selection.activeObject = mono;
};
}
EditorGUILayout.Space();
EditorGUILayout.Space();
}
}
protected void DrawFindRefWindowGUI()
{
EditorGUILayout.LabelField("<Select a GameObject In Scene>", EditorStyles.boldLabel);
EditorGUILayout.Space();
if (preTran != null)
EditorGUILayout.LabelField(preTran.name, EditorStyles.largeLabel);
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.LabelField("SceneReferences:", EditorStyles.boldLabel);
if (GUILayout.Button("ReFresh", GUILayout.Width(100)))
{
EditorApplication.delayCall += () =>
{
if (Selection.activeTransform == null)
{
ShowNotification("Select a GameObject In Scene");
return;
}
find_reference();
};
}
EditorGUILayout.Space();
EditorGUILayout.Space();
using (new EditorGUILayout.VerticalScope(GUI.skin.box))
{
reference_GUI();
}
}
#endregion
}
}
语文水平有限,表达不清晰。。。大家可以下载下来试一下,傻瓜式一键操作。
本次水文结束。