Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to find and specifically select missing mono scripts in Unity 2018.3?

Discussion in 'Editor & General Support' started by MrLucid72, Feb 8, 2019.

  1. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    962


    I went all day trying to find and edit different scripts to remove these, or select them all so I can remove. The closest I got was to select all with a missing script, but there are different KINDS of missing scripts where this triggers, with only detecting that the component is null.

    However, this is a very SPECIFIC type of null -- that screenshot above. Not any other form. Just the standard "was a script here, now there's not" missing script. Something I can mass select and delete (or just mass delete with no need to select it).

    I have thousands after converting from Nested Prefabs to Unity's new Prefab architecture -- it created mass amounts of garbage missing scripts that are false positives.

    I need to remove all of these en masse~

    However, I can't just detect if component is null. How can I specifically detect this kind of missing script? For example, some random things are being picked up like .... missing masks and random stuff that won't let me mass remove component because a select few are not the same form of missing script.

    I found one that LOOKS like it works, but as soon as I change scene or close Unity, it just crashes it (worked fine in 5.x, but not 2018.x). Another one just goes through prefabs in the project, but not in the hierarchy (non-prefabs or unsyncd ones).

    I've found no asset that actually has this working for 2018.3 ~ I'd happily even pay to mass cleanup these scripts if you can refer me to an asset.

    Here's what I got that's close

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections.Generic;
    4. using UnityEngine.SceneManagement;
    5.  
    6. /// <summary>
    7. /// I didn't make the core of this script. It's open source online somewhere.
    8. /// However, in doubt that none of these works, I don't remember the src link :/
    9. /// </summary>
    10. public class SelectGameObjectsWithMissingScripts : Editor
    11. {
    12.     [MenuItem("Utilities/Xblade/Select GameObjects With Missing Scripts #t",  // shift+t
    13.         priority = 1)]
    14.     static void SelectGameObjects()
    15.     {
    16.         //Get the current scene and all top-level GameObjects in the scene hierarchy
    17.         Scene currentScene = SceneManager.GetActiveScene();
    18.         GameObject[] rootObjects = currentScene.GetRootGameObjects();
    19.  
    20.         List<Object> objectsWithDeadLinks = new List<Object>();
    21.  
    22.         foreach (GameObject g in rootObjects)
    23.         {
    24.             foreach (Transform t in g.GetComponentsInChildren<Transform>(true))
    25.             {
    26.                 Component[] c = t.GetComponents<MonoBehaviour>();
    27.  
    28.                 foreach (Component _c in c)
    29.                 {
    30.                     // If the component is null, that means it's a missing script!
    31.                     if (_c == null)
    32.                     {
    33.                         // Add the sinner to our naughty-list
    34.                         objectsWithDeadLinks.Add(t.gameObject);
    35.                         Selection.activeGameObject = t.gameObject;
    36.                         Debug.Log($"{g.name}.{t.name} has a missing script!");
    37.                         break;
    38.                     }
    39.                 }
    40.             }
    41.         }
    42.  
    43.         // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    44.         //foreach (GameObject g in rootObjects)
    45.         //{
    46.         //    Transform[] childTransforms = g.GetComponentsInChildren<Transform>(true); // Include inactive
    47.         //    foreach (Transform t in childTransforms)
    48.         //    {
    49.         //        //Get all components on the GameObject, then loop through them
    50.  
    51.         //        Component[] components = t.GetComponents<MonoBehaviour>();
    52.         //        for (int i = 0; i < components.Length; i++)
    53.         //        {
    54.         //            Component currentComponent = components[i];
    55.  
    56.         //            //If the component is null, that means it's a missing script!
    57.         //            if (currentComponent == null)
    58.         //            {
    59.         //                //Add the sinner to our naughty-list
    60.         //                objectsWithDeadLinks.Add(t.gameObject);
    61.         //                Selection.activeGameObject = t.gameObject;
    62.         //                Debug.Log(t + " has a missing script!");
    63.         //                break;
    64.         //            }
    65.         //        }
    66.         //    }
    67.         //}
    68.         // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    69.  
    70.         if (objectsWithDeadLinks.Count > 0)
    71.         {
    72.             //Set the selection in the editor
    73.             Selection.objects = objectsWithDeadLinks.ToArray();
    74.         }
    75.         else
    76.         {
    77.             Debug.Log("No GameObjects in '" + currentScene.name + "' have missing scripts! Yay!");
    78.         }
    79.     }
    80. }
    Ignore the more-than-likely redundant loops, I'm trying different things and just dumping it here. It's successfully multi-selecting all the objs in the hierarchy that has a missing script, but I can't bulk remove it. There are some things in between that are "not the same kind of missing script". Idk.
     
    Last edited: Feb 9, 2019