编辑器扩展(查找当前场景里面所有有丢失引用的脚本)

一键查找当前场景中,所有挂载在物体上面的脚本,那些脚本的引用空了(引用丢失)

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace MyUtility
{
    public class FindObjRefsAllNullEditorWindow : EditorWindow
    {
        #region Window
        [MenuItem("Tools/MyUtility/FindAllObjRefsNull")]
        static void Open()
        {
            OpenWindow("FindAllObjRefsNull");
        }
        public static void OpenWindow(string windowTitle)
        {
            FindObjRefsAllNullEditorWindow window = GetWindow(windowTitle);
            window.position = new Rect(Screen.width / 2, Screen.height / 2, 500, 500);
            window.Show();
        }
        protected void ShowNotification(string msg)
        {
            this.ShowNotification(new GUIContent(msg));
        }

        Vector2 scrollPos;

        void OnGUI()
        {
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
            DrawWindowGUI();
            EditorGUILayout.EndScrollView();
        }
        #endregion

        void DrawWindowGUI()
        {
            EditorGUILayout.Space();
            refNullAll_GUI();
        }

        #region RefNullAll
        bool isShowRefNullAll = false;

        List referencesAll = new List();
        List fieldNames = new List();

        Transform preTran = null;


        void find_reference_Null()
        {
            referencesAll.Clear();
            fieldNames.Clear();
            List monos = new List();
            monos.Clear();
            // GetSceneTrans() 得到当前场景下所有transdorm节点
            List trans = GetSceneTrans();//Selection.activeTransform.gameObject.scene.name
            int len = trans.Count;
            for (int i = 0; i < len; i++)
            {
                Transform tran = trans[i];
                if (tran == null) continue;
                MonoBehaviour[] mono = tran.GetComponents();
                if (mono.Length > 0)
                {
                    monos.AddRange(mono);
                }
            }

            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 (fieldInfo.GetValue(mono) == null)
                    {
                        referencesAll.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 (f.GetValue(fieldInfo.GetValue(mono)) == null)
                            {
                                //Debug.Log("Find");
                                referencesAll.Add(mono);
                                fieldNames.Add(fieldInfo.Name + "/" + f.Name);
                            }
                        }
                    }
                }
            }
        }

      
        void refNullAll_GUI()
        {
            isShowRefNullAll = EditorGUILayout.Foldout(isShowRefNullAll, "CheckRefNullAllSceneGameObjects");

            if (!isShowRefNullAll) return;

            if (GUILayout.Button("ReFresh", GUILayout.Width(100)))
            {
                EditorApplication.delayCall += () =>
                {
                    find_reference_Null();
                };
            }
            EditorGUILayout.Space();
            EditorGUILayout.Space();


            using (new EditorGUILayout.VerticalScope(GUI.skin.box))
            {
                referenceNull_gui();
            }
        }

        void referenceNull_gui()
        {
            if (fieldNames.Count <= 0) return;
            //references.RemoveAll(r => r == null);
            int len = referencesAll.Count;
            for (int i = 0; i < len; i++)
            {
                MonoBehaviour mono = referencesAll[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();
            }
        }


        #endregion

        #region 私有内部方法


        void GetChildrenTrans(Transform transform, List 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);
                }
            }
        }

        List GetSceneTrans()     // string scene
        {
            List trans = new List();
            //GameObject[] roots = getSceneRootGameObjects(GetScene(scene));
            GameObject[] roots = getSceneRootGameObjects(GetScene());
            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;
        }

        GameObject[] getSceneRootGameObjects(Scene scene)
        {
            return scene.GetRootGameObjects();
        }

        Scene GetCurrentActiveScene()
        {
            return SceneManager.GetActiveScene();
        }
        Scene GetScene(string name)
        {
            return SceneManager.GetSceneByName(name);
            // return SceneManager.GetActiveScene();
        }
        public static Scene GetScene()
        {
            return SceneManager.GetActiveScene();
        }


        #endregion

    }
}

你可能感兴趣的:(编辑器扩展(查找当前场景里面所有有丢失引用的脚本))