x


How do I Remove null components ( i.e. "Missing(Mono Script)" ) via editor script?

I have made a script somewhat similar to this one: http://answers.unity3d.com/questions/5020/searching-a-project-for-missing-mono-script

But rather than just finding the null entries, I simply want to sweep through and delete them all. By that I mean remove the null references from the GameObjects's list of Components.

The documentation for GameObject.AddComponent notes that there is no such thing as RemoveComponent, requiring you to call Object.Destroy() to remove that entry. This is impossible because there is no object to Destroy.

Creating a new GameObject and adding the components of the old one to it would invalidate any references to it.

Is there a way to do this without laboriously clicking through the UI?

NEW EDIT: (in light of comments below)

Are these references to some funny objects representing a missing script that the overloaded == operator is treating as equal to null? No, because calling DestroyImmediate() does nothing, and trying to actually de-reference the pointer causes a null reference exception. It must be that there are null pointer entries in the list, and the list is not modifiable by editor script.

Here is the demonstration code:

[MenuItem("Custom/Remove Missing Script Entries")]
public static void Do() {
    foreach (Transform t in Selection.transforms) {
        Debug.Log(t.GetComponents(typeof(Component)).Length);
        foreach (Component c in t.GetComponents(typeof(Component))) {
            if (c == null){
                Debug.Log("NULL");
                // throw caution to the wind and destroy anyway!!! AHAHHAHAHAH!!!
                GameObject.DestroyImmediate(c);
                // awwww nothing happened.  still there.
            }
            else
                Debug.Log(c.GetType());
        }
    }
}
more ▼

asked Apr 15 '10 at 11:28 PM

DtBeloBrown gravatar image

DtBeloBrown
433 6 7 19

(comments are locked)
10|3000 characters needed characters left

8 answers: sort oldest

Have you actually tried calling "Destroy()" on the value which appears to be null? It may work, due to the slightly unusual way that objects which inherit from Unity's base Object deal with null references.

more ▼

answered Apr 16 '10 at 08:57 AM

duck gravatar image

duck ♦♦
41k 92 148 415

If I have understood you correctly, your suggestion did not work unfortunately. Is there somewhere I can read more about this "slightly unusual way"?

Apr 16 '10 at 04:46 PM DtBeloBrown

to clarify did you replace DestroyImediate() in the above script with Destroy()?

Jul 07 '10 at 06:55 PM lathomas64

I thought you couldn't use Object.Destroy in editor mode.. and if he's using Selection.transforms, doesn't that assume he's in editor mode?

Jul 11 '10 at 04:31 AM N1nja
(comments are locked)
10|3000 characters needed characters left

If calling Destroy isn't working on them, and they are actually a missing reference that is reporting null, could you just try setting the variable to null explicitly to get rid of the missing references? They should be cleaned up by mono if they are storing anything if you're worried about memory leaks.

more ▼

answered Jun 11 '10 at 10:56 PM

Murcho gravatar image

Murcho
2.7k 12 23 53

The question would be, which variable then to set to null (in the example above, c is a foreach iteration variable so you cannot set it to null). Setting my own local references to null shouldn't do anything because it is the references inside Unity that count. I tried your suggestion anyway, by setting the some elements of the array I get back from GetComponents() to null, as expected it didn't work. If only there was a SetComponents() to give my modified array back to Unity, you might be on to something.

Jun 15 '10 at 12:12 AM DtBeloBrown
(comments are locked)
10|3000 characters needed characters left

I believe there is currently no easy solution to do this in scripting. The internal implementation when you pick "Remove Component" from the popup menu is in C++, where all MonoBehaviour components are just belonging to a MonoBehaviour class. Once these are passed to C#, they get the class types of their scripts, or, if the script is empty, then null, which cannot be used to destroy the object.

You might be able to get a pointer reference to the actual MonoBehaviour component which you could call delete on, by iterating through all the GameObjects properties using the SerializedObject class, but that probably takes same time to get to work, if it is possible at all.

more ▼

answered Jun 28 '10 at 08:50 AM

jonas echterhoff gravatar image

jonas echterhoff ♦♦
9.8k 7 23 104

Just want to add that i've just tried to get a usable reference to the MonoBehaviour, but it seems there's really no way. I used the SerializedObject class to get all component references, but even there it's just null.

I've digged quite deep into the editor and realized that the default inspector also uses a serialized object to display the GUI. The editor creates a SerializedObject from a reference, but this reference seems to get passed from the native code side. Maybe it's possible to "hack" into the private members of the editor that displays the MonoBehaviour with reflection, but beside that it's not a good idea to use relfection that way, it won't help much since the information what MonoScript was used by this Behaviour is gone.

May 12 '12 at 03:20 PM Bunny83
(comments are locked)
10|3000 characters needed characters left

When you create the object, just be sure to use Object.hideFlags = HideFlags.DontSave;

assuming that is you're creating it program-maticaly.. otherwise, there isn't much you can do if the object is null. it will be cached for later referencing.

more ▼

answered Jul 11 '10 at 04:28 AM

N1nja gravatar image

N1nja
445 22 28 37

(comments are locked)
10|3000 characters needed characters left

Is there a valid solution to this yet ? I have a scene with up to a thousand objects and it will take me hours to remove a bad script that was caused from a click drag when unity chugged..... !!!!!!

more ▼

answered Apr 08 '11 at 10:55 PM

Jeston gravatar image

Jeston
419 27 31 34

Not an answer. Please post a comment instead

May 12 '12 at 04:25 PM kalvinlyle
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x1673
x348
x132
x1

asked: Apr 15 '10 at 11:28 PM

Seen: 4752 times

Last Updated: Feb 22 at 03:18 PM