├── Editor.meta ├── Editor ├── MissingScriptChecker.cs ├── MissingScriptChecker.cs.meta ├── MissingScriptCheckerSettings.cs ├── MissingScriptCheckerSettings.cs.meta ├── MissingScriptCheckerSettingsProvider.cs ├── MissingScriptCheckerSettingsProvider.cs.meta ├── UniMissingScriptChecker.asmdef └── UniMissingScriptChecker.asmdef.meta ├── README.md ├── README.md.meta ├── package.json └── package.json.meta /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e9a1358f4f37f1c408c227f993f06f33 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/MissingScriptChecker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using UnityEditor; 4 | using UnityEngine; 5 | 6 | namespace UniMissingScriptChecker 7 | { 8 | /// 9 | /// Missing Script が存在したら Unity を再生できなくするエディタ拡張 10 | /// 11 | [InitializeOnLoad] 12 | public static class MissingScriptChecker 13 | { 14 | //================================================================================ 15 | // クラス 16 | //================================================================================ 17 | /// 18 | /// Missing Script の情報を管理するクラス 19 | /// 20 | public sealed class MissingScriptData 21 | { 22 | /// 23 | /// 参照が設定されていないパラメータを所持するコンポーネント 24 | /// 25 | public GameObject GameObject { get; } 26 | 27 | public MissingScriptData( GameObject gameObject ) 28 | { 29 | GameObject = gameObject; 30 | } 31 | } 32 | 33 | //================================================================================ 34 | // 関数(static) 35 | //================================================================================ 36 | /// 37 | /// コンストラクタ 38 | /// 39 | static MissingScriptChecker() 40 | { 41 | EditorApplication.playModeStateChanged += OnChange; 42 | } 43 | 44 | /// 45 | /// Unity のプレイモードの状態が変化した時に呼び出されます 46 | /// 47 | private static void OnChange( PlayModeStateChange state ) 48 | { 49 | if ( state != PlayModeStateChange.ExitingEditMode ) return; 50 | 51 | var settings = MissingScriptCheckerSettings.LoadFromEditorPrefs(); 52 | 53 | if ( !settings.IsEnable ) return; 54 | 55 | var list = Validate().ToArray(); 56 | 57 | if ( list.Length <= 0 ) return; 58 | 59 | var logFormat = settings.LogFormat; 60 | 61 | foreach ( var n in list ) 62 | { 63 | var message = logFormat; 64 | message = message.Replace( "[GameObjectName]", n.GameObject.name ); 65 | message = message.Replace( "[GameObjectRootPath]", GetRootPath( n.GameObject ) ); 66 | 67 | Debug.LogError( message, n.GameObject ); 68 | } 69 | 70 | EditorApplication.isPlaying = false; 71 | } 72 | 73 | /// 74 | /// Missing Script の一覧を返します 75 | /// 76 | private static IEnumerable Validate() 77 | { 78 | var gameObjects = Resources 79 | .FindObjectsOfTypeAll() 80 | .Where( c => c.scene.isLoaded ) 81 | .Where( c => c.hideFlags == HideFlags.None ) 82 | ; 83 | 84 | foreach ( var gameObject in gameObjects ) 85 | { 86 | var count = GameObjectUtility.GetMonoBehavioursWithMissingScriptCount( gameObject ); 87 | 88 | if ( count <= 0 ) continue; 89 | 90 | var data = new MissingScriptData( gameObject ); 91 | 92 | yield return data; 93 | } 94 | } 95 | 96 | /// 97 | /// ゲームオブジェクトのルートからのパスを返します 98 | /// 99 | private static string GetRootPath( this GameObject gameObject ) 100 | { 101 | var path = gameObject.name; 102 | var parent = gameObject.transform.parent; 103 | 104 | while ( parent != null ) 105 | { 106 | path = parent.name + "/" + path; 107 | parent = parent.parent; 108 | } 109 | 110 | return path; 111 | } 112 | } 113 | } -------------------------------------------------------------------------------- /Editor/MissingScriptChecker.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ca7809e9a1ab99a41b079b7ff5b1aa40 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/MissingScriptCheckerSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor; 3 | using UnityEngine; 4 | 5 | namespace UniMissingScriptChecker 6 | { 7 | /// 8 | /// 設定を管理するクラス 9 | /// 10 | [Serializable] 11 | internal sealed class MissingScriptCheckerSettings 12 | { 13 | //================================================================================ 14 | // 定数 15 | //================================================================================ 16 | private const string KEY = "UniMissingScriptChecker"; 17 | 18 | //================================================================================ 19 | // 変数(SerializeField) 20 | //================================================================================ 21 | [SerializeField] private bool m_isEnable = false; 22 | [SerializeField] private string m_logFormat = "Missing Script が存在します:[GameObjectRootPath]"; 23 | 24 | //================================================================================ 25 | // プロパティ 26 | //================================================================================ 27 | public bool IsEnable 28 | { 29 | get => m_isEnable; 30 | set => m_isEnable = value; 31 | } 32 | 33 | public string LogFormat 34 | { 35 | get => m_logFormat; 36 | set => m_logFormat = value; 37 | } 38 | 39 | //================================================================================ 40 | // 関数(static) 41 | //================================================================================ 42 | /// 43 | /// EditorPrefs から読み込みます 44 | /// 45 | public static MissingScriptCheckerSettings LoadFromEditorPrefs() 46 | { 47 | var json = EditorPrefs.GetString( KEY ); 48 | var settings = JsonUtility.FromJson( json ) ?? 49 | new MissingScriptCheckerSettings(); 50 | 51 | return settings; 52 | } 53 | 54 | /// 55 | /// EditorPrefs に保存します 56 | /// 57 | public static void SaveToEditorPrefs( MissingScriptCheckerSettings setting ) 58 | { 59 | var json = JsonUtility.ToJson( setting ); 60 | 61 | EditorPrefs.SetString( KEY, json ); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /Editor/MissingScriptCheckerSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae0c6728e5b464f4d9234861266ceb37 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/MissingScriptCheckerSettingsProvider.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace UniMissingScriptChecker 5 | { 6 | /// 7 | /// Preferences における設定画面を管理するクラス 8 | /// 9 | internal sealed class MissingScriptCheckerSettingsProvider : SettingsProvider 10 | { 11 | //================================================================================ 12 | // 関数 13 | //================================================================================ 14 | /// 15 | /// コンストラクタ 16 | /// 17 | public MissingScriptCheckerSettingsProvider( string path, SettingsScope scope ) 18 | : base( path, scope ) 19 | { 20 | } 21 | 22 | /// 23 | /// GUI を描画する時に呼び出されます 24 | /// 25 | public override void OnGUI( string searchContext ) 26 | { 27 | var settings = MissingScriptCheckerSettings.LoadFromEditorPrefs(); 28 | 29 | using ( var checkScope = new EditorGUI.ChangeCheckScope() ) 30 | { 31 | settings.IsEnable = EditorGUILayout.Toggle( "Enabled", settings.IsEnable ); 32 | settings.LogFormat = EditorGUILayout.TextField( "Log Format", settings.LogFormat ); 33 | 34 | if ( checkScope.changed ) 35 | { 36 | MissingScriptCheckerSettings.SaveToEditorPrefs( settings ); 37 | } 38 | 39 | EditorGUILayout.HelpBox( "Log Format で使用できるタグ", MessageType.Info ); 40 | 41 | EditorGUILayout.TextArea 42 | ( 43 | @"[GameObjectName] 44 | [GameObjectRootPath]" 45 | ); 46 | 47 | if ( GUILayout.Button( "Use Default" ) ) 48 | { 49 | settings = new MissingScriptCheckerSettings(); 50 | MissingScriptCheckerSettings.SaveToEditorPrefs( settings ); 51 | } 52 | } 53 | } 54 | 55 | //================================================================================ 56 | // 関数(static) 57 | //================================================================================ 58 | /// 59 | /// Preferences にメニューを追加します 60 | /// 61 | [SettingsProvider] 62 | private static SettingsProvider Create() 63 | { 64 | var path = "Preferences/UniMissingScriptChecker"; 65 | var provider = new MissingScriptCheckerSettingsProvider( path, SettingsScope.User ); 66 | 67 | return provider; 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /Editor/MissingScriptCheckerSettingsProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fb0ee74a8db846a4aab375c2e7fcb781 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/UniMissingScriptChecker.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "UniMissingScriptChecker", 3 | "references": [], 4 | "includePlatforms": [ 5 | "Editor" 6 | ], 7 | "excludePlatforms": [], 8 | "allowUnsafeCode": false, 9 | "overrideReferences": false, 10 | "precompiledReferences": [], 11 | "autoReferenced": true, 12 | "defineConstraints": [], 13 | "versionDefines": [], 14 | "noEngineReferences": false 15 | } -------------------------------------------------------------------------------- /Editor/UniMissingScriptChecker.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 55843cf9de1cf764c88e4ab062656d90 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Uni Missing Script Checker 2 | 3 | Missing Script が存在したら Unity を再生できなくするエディタ拡張 4 | 5 | ## 使用例 6 | 7 | ![2020-05-05_195706](https://user-images.githubusercontent.com/6134875/81059029-9de99f80-8f0a-11ea-9cf2-0525c53d2cfd.png) 8 | 9 | ![Image (17)](https://user-images.githubusercontent.com/6134875/81059033-9fb36300-8f0a-11ea-9077-d2688114bf98.gif) 10 | 11 | ## 設定 12 | 13 | ![2020-05-09_105815](https://user-images.githubusercontent.com/6134875/81461006-fdce9780-91e3-11ea-8f9b-71868e3d00c9.png) 14 | 15 | Preferences から設定を変更できます 16 | 17 | |項目|内容| 18 | |:--|:--| 19 | |Enabled|有効かどうか(デフォルトは OFF)| 20 | |Log Format|エラーログのフォーマット| -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 78bb37c198725244a862de80cd5e6351 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.baba-s.uni-missing-script-checker", 3 | "displayName": "UniMissingScriptChecker", 4 | "version": "1.0.0", 5 | "unity": "2019.2", 6 | "author": "baba-s" 7 | } -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aade822f36e98c6458be2e0668c7c457 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------