Skip to content

Instantly share code, notes, and snippets.

@mingrui
Created July 28, 2017 02:15
Show Gist options
  • Save mingrui/7af9f3f35b4c490b90cd762a46f7af93 to your computer and use it in GitHub Desktop.
Save mingrui/7af9f3f35b4c490b90cd762a46f7af93 to your computer and use it in GitHub Desktop.
Unity Editor Script to help cleaning up missing script references on gameobjects
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class CleanupMissingScriptsHelper{
[MenuItem("Edit/Cleanup Missing Scripts")]
static void CleanupMissingScripts() {
for (int i = 0; i < Selection.gameObjects.Length; i++) {
var gameObject = Selection.gameObjects[i];
// We must use the GetComponents array to actually detect missing components
var components = gameObject.GetComponents<Component>();
// Create a serialized object so that we can edit the component list
var serializedObject = new SerializedObject(gameObject);
// Find the component list property
var prop = serializedObject.FindProperty("m_Component");
// Track how many components we've removed
int r = 0;
// Iterate over all components
for (int j = 0; j < components.Length; j++) {
// Check if the ref is null
if (components[j] == null) {
// If so, remove from the serialized component array
prop.DeleteArrayElementAtIndex(j - r);
// Increment removed count
r++;
}
}
// Apply our changes to the game object
serializedObject.ApplyModifiedProperties();
}
}
[MenuItem("Edit/Recursive Cleanup Missing Scripts")]
static void RecursiveCleanupMissingScripts() {
Transform[] allTransforms = Selection.gameObjects[0].GetComponentsInChildren<Transform>(true);
for (int i = 0; i < allTransforms.Length; i++) {
var gameObject = allTransforms[i].gameObject;
// We must use the GetComponents array to actually detect missing components
var components = gameObject.GetComponents<Component>();
// Create a serialized object so that we can edit the component list
var serializedObject = new SerializedObject(gameObject);
// Find the component list property
var prop = serializedObject.FindProperty("m_Component");
// Track how many components we've removed
int r = 0;
// Iterate over all components
for (int j = 0; j < components.Length; j++) {
// Check if the ref is null
if (components[j] == null) {
// If so, remove from the serialized component array
prop.DeleteArrayElementAtIndex(j - r);
// Increment removed count
r++;
}
}
// Apply our changes to the game object
serializedObject.ApplyModifiedProperties();
}
}
}
@AnriEU
Copy link

AnriEU commented Jul 21, 2021

Unity 2020 -
It is not allowed to modify the data property
UnityEditor.SerializedProperty:DeleteArrayElementAtIndex (int)
CleanupMissingScriptsHelper:CleanupMissingScripts () (at Assets/Game/Scripts/AnriStudio/CleanupMissingScriptsHelper.cs:33)

@XeniaPhe
Copy link

Turns out unity has a method that does exactly that, I forked and edited the code and it works

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment