using UnityEngine; using UnityEditor; using System.IO; public class RemoveMissingScriptsFromFolder { [MenuItem("Tools/Cleanup/Remove Missing Scripts (Select Folder)")] static void RemoveFromFolder() { // Ask user to pick a folder string absFolder = EditorUtility.OpenFolderPanel( "Select folder to clean prefabs", Application.dataPath, "" ); if (string.IsNullOrEmpty(absFolder)) return; // Must be inside Assets if (!absFolder.StartsWith(Application.dataPath)) { EditorUtility.DisplayDialog("Invalid Folder", "Please select a folder inside your project's Assets folder.", "OK"); return; } // Convert to relative path: Assets/... string relFolder = "Assets" + absFolder.Substring(Application.dataPath.Length); string[] prefabGuids = AssetDatabase.FindAssets("t:Prefab", new[] { relFolder }); int cleaned = 0; int scanned = 0; try { AssetDatabase.StartAssetEditing(); foreach (string guid in prefabGuids) { string path = AssetDatabase.GUIDToAssetPath(guid); scanned++; GameObject instance = PrefabUtility.LoadPrefabContents(path); if (!instance) continue; bool changed = false; // Root changed |= GameObjectUtility.RemoveMonoBehavioursWithMissingScript(instance) > 0; // Children foreach (Transform t in instance.GetComponentsInChildren(true)) { changed |= GameObjectUtility.RemoveMonoBehavioursWithMissingScript(t.gameObject) > 0; } if (changed) { PrefabUtility.SaveAsPrefabAsset(instance, path); cleaned++; } PrefabUtility.UnloadPrefabContents(instance); } } finally { AssetDatabase.StopAssetEditing(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } EditorUtility.DisplayDialog( "Cleanup finished", $"Scanned: {scanned}\nCleaned: {cleaned}", "OK" ); } }