Created
December 18, 2017 14:49
-
-
Save marcelschmidtdev/70037fd36e3a9be1c4808891e8cdf537 to your computer and use it in GitHub Desktop.
Searching for components with missing scripts and removes them
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using UnityEditor; | |
using UnityEditor.SceneManagement; | |
using UnityEngine; | |
public class RemoveMissingScriptComponents | |
{ | |
[MenuItem ("TOOLS/Remove Missing Scripts")] | |
public static void Run () | |
{ | |
try | |
{ | |
FindAndRemoveMissingScripts (); | |
} | |
catch (Exception e) | |
{ | |
EditorUtility.ClearProgressBar (); | |
Debug.LogError (e.Message); | |
throw e; | |
} | |
} | |
private static void FindAndRemoveMissingScripts () | |
{ | |
Debug.Log ("Scenes: " + EditorBuildSettings.scenes.Length); | |
EditorUtility.DisplayProgressBar ("Find Missing Script Components", "Loading scenes from build settings...", 0.2f); | |
for (int i = 0; i < EditorBuildSettings.scenes.Length; i++) | |
{ | |
EditorSceneManager.OpenScene (EditorBuildSettings.scenes[i].path, OpenSceneMode.Additive); | |
} | |
GameObject[] sceneObjects = GetAllHierarchyObjects (); | |
EditorUtility.DisplayProgressBar ("Find Missing Script Components", "Searching for missing MonoBehaviours...", 0.4f); | |
StringBuilder sb = new StringBuilder (); | |
List<SerializedObject> missingComponents = FindObjectsWithMissingComponents (sceneObjects, sb); | |
EditorUtility.DisplayProgressBar ("Find Missing Script Components", "Searching for missing MonoBehaviours...", 0.5f); | |
if (missingComponents.Count > 0) | |
{ | |
sb.Insert (0, "Scenes will be modified and saved:\n\n"); | |
if (EditorUtility.DisplayDialog ("Remove missing script components?", sb.ToString (), "Remove All", "Cancel")) | |
{ | |
foreach (SerializedObject serializedObject in missingComponents) | |
{ | |
SerializedProperty serializedProperty = serializedObject.GetIterator (); | |
while (serializedProperty.Next (true)) | |
{ | |
RemoveMissingScriptComponentProperty (serializedProperty, serializedObject.context); | |
} | |
serializedObject.ApplyModifiedProperties (); | |
serializedObject.Update (); | |
EditorSceneManager.MarkSceneDirty ((serializedObject.targetObject as GameObject).scene); | |
} | |
SaveScenes (); | |
} | |
} | |
else | |
{ | |
EditorUtility.DisplayDialog ("No missing script components found!", "Nothing to do here :)", "Ok, cool!"); | |
} | |
EditorUtility.ClearProgressBar (); | |
} | |
private static GameObject[] GetAllHierarchyObjects () | |
{ | |
// Filter out hidden GOs and referenced prefabs | |
return Resources.FindObjectsOfTypeAll<GameObject> () | |
.Where (o => string.IsNullOrEmpty (AssetDatabase.GetAssetPath (o)) && o.hideFlags == HideFlags.None) | |
.ToArray (); | |
} | |
private static List<SerializedObject> FindObjectsWithMissingComponents (GameObject[] sceneObjects, StringBuilder sb) | |
{ | |
List<SerializedObject> missingComponents = new List<SerializedObject> (); | |
for (int i = 0; i < sceneObjects.Length; i++) | |
{ | |
Component[] components = sceneObjects[i].GetComponents<Component> (); | |
for (int j = 0; j < components.Length; j++) | |
{ | |
if (components[j] == null) | |
{ | |
missingComponents.Add (new SerializedObject (sceneObjects[i])); | |
sb.AppendLine (sceneObjects[i].transform.root.name + " -> " + sceneObjects[i].name); | |
} | |
} | |
} | |
return missingComponents; | |
} | |
private static void RemoveMissingScriptComponentProperty (SerializedProperty serializedProperty, UnityEngine.Object context) | |
{ | |
if (serializedProperty.propertyType == SerializedPropertyType.ObjectReference && | |
serializedProperty.objectReferenceValue == null && | |
serializedProperty.objectReferenceInstanceIDValue != 0) | |
{ | |
bool success = serializedProperty.DeleteCommand (); | |
if (success == false) | |
{ | |
Debug.LogError ("Missing component could not be deleted!", context); | |
throw new Exception (); | |
} | |
} | |
} | |
private static void SaveScenes () | |
{ | |
bool success = EditorSceneManager.SaveOpenScenes (); | |
if (success == false) | |
{ | |
Debug.LogError ("Error saving scenes!"); | |
throw new Exception (); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment