├── .gitignore ├── Assets ├── MissingScripts.meta └── MissingScripts │ ├── Editor.meta │ ├── Editor │ ├── MissingScriptsListWindow.cs │ └── MissingScriptsListWindow.cs.meta │ ├── README.txt │ └── README.txt.meta ├── README.md └── UNLICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /[Pp]ackages/ 7 | /Assets/AssetStoreTools* 8 | /ProjectSettings/ 9 | /_build/ 10 | /_work/ 11 | /UnityPackageManager/ 12 | 13 | # Visual Studio cache directory 14 | .vs/ 15 | 16 | # Autogenerated VS/MD/Consulo solution and project files 17 | ExportedObj/ 18 | .consulo/ 19 | *.csproj 20 | *.unityproj 21 | *.sln 22 | *.suo 23 | *.tmp 24 | *.user 25 | *.userprefs 26 | *.pidb 27 | *.booproj 28 | *.svd 29 | *.pdb 30 | *.opendb 31 | 32 | # Unity3D generated meta files 33 | *.pidb.meta 34 | *.pdb.meta 35 | 36 | # Unity3D Generated File On Crash Reports 37 | sysinfo.txt 38 | 39 | # Builds 40 | *.apk 41 | *.unitypackage 42 | -------------------------------------------------------------------------------- /Assets/MissingScripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 132354dd8ef3aa146beb96d3736e7b0a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/MissingScripts/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 993e145122b6bfb4a96b91c45ec6ce79 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/MissingScripts/Editor/MissingScriptsListWindow.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | using UnityEditor; 4 | 5 | 6 | namespace plyoung 7 | { 8 | public class MissingScriptsListWindow : EditorWindow 9 | { 10 | private static readonly GUIContent GC_Find = new GUIContent("Find"); 11 | private static readonly GUIContent[] GC_Opt = new[] { new GUIContent("In Open Scene(s)"), new GUIContent("On Prefabs") }; 12 | private static readonly GUIContent GC_Close = new GUIContent("Close"); 13 | 14 | private static GUIStyle PingButtonStyle; 15 | 16 | private class Info 17 | { 18 | public Object obj; 19 | public GUIContent path; 20 | } 21 | 22 | private int opt = 0; 23 | private Vector2 scroll; 24 | private List entries = new List(); 25 | 26 | // ------------------------------------------------------------------------------------------------------------------ 27 | 28 | [MenuItem("Window/Missing Scripts Finder")] 29 | private static void ShowWindow() 30 | { 31 | GetWindow(true, "Missing Scripts", true); 32 | } 33 | 34 | private void OnGUI() 35 | { 36 | if (PingButtonStyle == null) 37 | { 38 | PingButtonStyle = new GUIStyle(EditorStyles.miniButton) { alignment = TextAnchor.MiddleLeft }; 39 | } 40 | 41 | EditorGUILayout.BeginHorizontal(); 42 | { 43 | if (GUILayout.Button(GC_Find, EditorStyles.miniButton, GUILayout.Width(100f))) Find(); 44 | opt = EditorGUILayout.Popup(opt, GC_Opt); 45 | GUILayout.FlexibleSpace(); 46 | if (GUILayout.Button(GC_Close, EditorStyles.miniButton, GUILayout.Width(100f))) Close(); 47 | EditorGUILayout.Space(); 48 | } 49 | EditorGUILayout.EndHorizontal(); 50 | EditorGUILayout.Space(); 51 | 52 | scroll = EditorGUILayout.BeginScrollView(scroll); 53 | { 54 | foreach (var e in entries) 55 | { 56 | if (GUILayout.Button(e.path, PingButtonStyle, GUILayout.ExpandWidth(true))) 57 | { 58 | EditorGUIUtility.PingObject(e.obj); 59 | Selection.activeObject = e.obj; 60 | } 61 | } 62 | 63 | GUILayout.Space(50); 64 | GUILayout.FlexibleSpace(); 65 | } 66 | EditorGUILayout.EndScrollView(); 67 | } 68 | 69 | private void Find() 70 | { 71 | entries.Clear(); 72 | GameObject[] gos = Resources.FindObjectsOfTypeAll(); 73 | 74 | foreach (var go in gos) 75 | { 76 | // only want scene objects or prefabs? 77 | if ((opt == 0 && !go.scene.IsValid()) || 78 | (opt == 1 && go.scene.IsValid())) continue; 79 | 80 | // do not add again if prefab already added 81 | // (TODO: can change this once nested prefabs are supported) 82 | if (opt == 1) 83 | { 84 | GameObject top = PrefabUtility.FindPrefabRoot(go); 85 | foreach (Info n in entries) if (n.obj == top) { top = null; break; } 86 | if (top == null) continue; // set to null when dupe found 87 | } 88 | 89 | // check if there are missing components on it 90 | int count = 0; 91 | Component[] cos = go.GetComponents(); 92 | foreach (var co in cos) if (co == null) count++; 93 | if (count == 0) continue; 94 | 95 | // create label 96 | Transform tr = go.transform.parent; 97 | Info nfo = new Info() 98 | { 99 | path = new GUIContent(go.name), 100 | obj = opt == 0 ? go : PrefabUtility.FindPrefabRoot(go) 101 | }; 102 | entries.Add(nfo); 103 | while (tr != null) 104 | { 105 | nfo.path.text = string.Format("{0}/{1}", tr.name, nfo.path.text); 106 | tr = tr.parent; 107 | } 108 | 109 | nfo.path.text = string.Format("[{0}] {1}", count, nfo.path.text); 110 | } 111 | 112 | // sort by path 113 | entries.Sort((a, b) => a.path.text.CompareTo(b.path.text)); 114 | } 115 | 116 | // ------------------------------------------------------------------------------------------------------------------ 117 | } 118 | } -------------------------------------------------------------------------------- /Assets/MissingScripts/Editor/MissingScriptsListWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 85f55e85e23e6f74a8830a7b65b00359 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/MissingScripts/README.txt: -------------------------------------------------------------------------------- 1 | # Missing Scripts Finder 2 | 3 | This simple panel helps you quickly identify objects in the open scene, or prefabs, that have missing scripts. 4 | It can be opened from menu: `Window > Missing Scripts Finder`. 5 | Click on a button in the list that comes up, if any, to quickly navigate to the object in question. 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Assets/MissingScripts/README.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0f58f613bb67e3a4d96e6ca8015d2260 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Missing Scripts Finder 2 | 3 | This simple panel helps you quickly identify objects in the open scene, or prefabs, that have missing scripts. It can be opened from menu: `Window > Missing Scripts Finder`. Click on a button in the list that comes up, if any, to quickly navigate to the object in question. 4 | 5 | ![screenshot](https://user-images.githubusercontent.com/837362/40116005-9da66dee-5912-11e8-9cdc-9294895e84d8.png) 6 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | --------------------------------------------------------------------------------