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

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

作者: UnityChan | 来源:发表于2019-10-08 15:34 被阅读0次

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

    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<FindObjRefsAllNullEditorWindow>(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<MonoBehaviour> referencesAll = new List<MonoBehaviour>();
            List<string> fieldNames = new List<string>();
    
            Transform preTran = null;
    
    
            void find_reference_Null()
            {
                referencesAll.Clear();
                fieldNames.Clear();
                List<MonoBehaviour> monos = new List<MonoBehaviour>();
                monos.Clear();
                // GetSceneTrans() 得到当前场景下所有transdorm节点
                List<Transform> 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<MonoBehaviour>();
                    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<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);
                    }
                }
            }
    
            List<Transform> GetSceneTrans()     // string scene
            {
                List<Transform> trans = new List<Transform>();
                //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
    
        }
    }
    
    

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/ovpmyctx.html