1- using UnityEditor ;
1+ using System . Diagnostics ;
2+ using UnityEditor ;
3+ using UnityEditor . Compilation ;
24using UnityEngine ;
35
46namespace KoganeUnityLib
57{
6- [ InitializeOnLoad ]
8+ /// <summary>
9+ /// バックグラウンドでコンパイルを開始するためのエディタ拡張
10+ /// </summary>
711 public static class UnityCompileInBackground
812 {
9- private const string NAME = "UnityCompileInBackground" ;
10- private const string KEY_IS_ENABLE = NAME + "-IsEnable" ;
11- private const string KEY_WAIT_TIME = NAME + "-WaitTime" ;
12- private const string KEY_IS_ENABLE_DEBUG_LOG = NAME + "-IsEnableDebugLog" ;
13-
14- private static bool m_isEnable ;
15- private static bool m_isEnableDebugLog ;
16- private static float m_waitTime ;
17- private static double m_time ;
18- private static bool m_isLoaded ;
19-
20- static UnityCompileInBackground ( )
13+ //==============================================================================
14+ // 定数
15+ //==============================================================================
16+ private const string CONSOLE_APP_PATH = @"UnityCompileInBackground/Editor/UnityCompileInBackground-Watcher.exe" ;
17+
18+ //==============================================================================
19+ // 変数
20+ //==============================================================================
21+ private static Process m_process ; // ファイル監視ツールのプロセス
22+ private static bool m_isRefresh ; // コンパイルを開始する場合 true
23+
24+ //==============================================================================
25+ // 関数
26+ //==============================================================================
27+ /// <summary>
28+ /// Unity エディタが起動した時に呼び出されます
29+ /// </summary>
30+ [ InitializeOnLoadMethod ]
31+ private static void Init ( )
2132 {
22- m_time = EditorApplication . timeSinceStartup ;
23- EditorApplication . update += OnUpdate ;
24- }
33+ // ファイル監視ツールを起動します
34+ // ツールからメッセージを受信したらコンパイルを開始します
35+ var dataPath = Application . dataPath ;
36+ var filename = dataPath + "/" + CONSOLE_APP_PATH ;
37+ var path = Application . dataPath ;
38+ var arguments = string . Format ( @"-p ""{0}"" -w 0" , path ) ;
39+ var windowStyle = ProcessWindowStyle . Hidden ;
40+
41+ var info = new ProcessStartInfo
42+ {
43+ FileName = filename ,
44+ UseShellExecute = false ,
45+ RedirectStandardOutput = true ,
46+ CreateNoWindow = true ,
47+ WindowStyle = windowStyle ,
48+ Arguments = arguments ,
49+ } ;
2550
26- private static void Load ( )
27- {
28- if ( m_isLoaded ) return ;
51+ m_process = Process . Start ( info ) ;
52+ m_process . OutputDataReceived += OnReceived ;
53+ m_process . BeginOutputReadLine ( ) ;
2954
30- m_isLoaded = true ;
55+ UnityEngine . Debug . Log ( "[UnityCompileInBackground] Start Watching" ) ;
3156
32- m_isEnable = EditorPrefs . GetBool ( KEY_IS_ENABLE , true ) ;
33- m_waitTime = EditorPrefs . GetFloat ( KEY_WAIT_TIME , 1 ) ;
34- m_isEnableDebugLog = EditorPrefs . GetBool ( KEY_IS_ENABLE_DEBUG_LOG , false ) ;
57+ EditorApplication . update += OnUpdate ;
58+ EditorApplication . quitting += OnQuit ;
59+ CompilationPipeline . assemblyCompilationStarted += OnCompilationStarted ;
3560 }
3661
37- private static void OnUpdate ( )
62+ /// <summary>
63+ /// Unity エディタが終了する時に呼び出されます
64+ /// </summary>
65+ private static void OnQuit ( )
3866 {
39- Load ( ) ;
40-
41- if ( ! m_isEnable ) return ;
42- if ( EditorApplication . isCompiling ) return ;
43- if ( EditorApplication . isUpdating ) return ;
44- if ( EditorApplication . timeSinceStartup - m_time < m_waitTime ) return ;
45-
46- m_time = EditorApplication . timeSinceStartup ;
47- AssetDatabase . Refresh ( ) ;
48-
49- if ( ! m_isEnableDebugLog ) return ;
50-
51- Debug . LogFormat ( "[ {0} ] Refresh" , NAME ) ;
67+ Dispose ( ) ;
5268 }
5369
54- #if ! UNITY_2018_3_OR_NEWER
55- [ PreferenceItem ( "Compile in BG" ) ]
56- #endif
57- private static void OnGUI ( )
70+ /// <summary>
71+ /// コンパイルが開始した時に呼び出されます
72+ /// </summary>
73+ private static void OnCompilationStarted ( string _ )
5874 {
59- Load ( ) ;
60-
61- EditorGUI . BeginChangeCheck ( ) ;
75+ Dispose ( ) ;
76+ }
6277
63- m_isEnable = EditorGUILayout . Toggle ( "Enabled" , m_isEnable ) ;
64- m_waitTime = MultipleFloor ( EditorGUILayout . Slider ( "Wait Time ( sec )" , m_waitTime , 0 , 10 ) , 0.1f ) ;
65- m_isEnableDebugLog = EditorGUILayout . Toggle ( "Enabled Debug Log" , m_isEnableDebugLog ) ;
78+ /// <summary>
79+ /// ファイル監視ツールを止めます
80+ /// </summary>
81+ private static void Dispose ( )
82+ {
83+ // すでに止まっている場合は何も行いません
84+ if ( m_process == null ) return ;
6685
67- if ( EditorGUI . EndChangeCheck ( ) )
86+ if ( ! m_process . HasExited )
6887 {
69- EditorPrefs . SetBool ( KEY_IS_ENABLE , m_isEnable ) ;
70- EditorPrefs . SetFloat ( KEY_WAIT_TIME , m_waitTime ) ;
71- EditorPrefs . SetBool ( KEY_IS_ENABLE_DEBUG_LOG , m_isEnableDebugLog ) ;
88+ m_process . Kill ( ) ;
7289 }
90+ m_process . Dispose ( ) ;
91+ m_process = null ;
92+
93+ UnityEngine . Debug . Log ( "[UnityCompileInBackground] Stop Watching" ) ;
7394 }
7495
75- #if UNITY_2018_3_OR_NEWER
76- [ SettingsProvider ]
77- public static SettingsProvider CreateSettingsProvider ( )
96+ /// <summary>
97+ /// エディタの更新タイミングで呼び出されます
98+ /// </summary>
99+ private static void OnUpdate ( )
78100 {
79- var path = "Preferences/" + NAME ;
80- var provider = new SettingsProvider ( path , SettingsScope . User )
81- {
82- label = NAME ,
83- guiHandler = _ => OnGUI ( ) ,
84- keywords = new [ ] { NAME , "Enabled" , "Wait Time ( sec )" } ,
85- } ;
101+ // コンパイルフラグが立っていない場合、コンパイル中の場合、
102+ // リフレッシュ中の場合はここで処理を止めます
103+ if ( ! m_isRefresh ) return ;
104+ if ( EditorApplication . isCompiling ) return ;
105+ if ( EditorApplication . isUpdating ) return ;
106+
107+ // コンパイルを開始します
108+ UnityEngine . Debug . Log ( "[UnityCompileInBackground] Start Compiling" ) ;
86109
87- return provider ;
110+ m_isRefresh = false ;
111+
112+ AssetDatabase . Refresh ( ) ;
88113 }
89- #endif
90114
91- private static float MultipleFloor ( float value , float multiple )
115+ /// <summary>
116+ /// ファイル監視ツールからメッセージを受信した時に呼び出されます
117+ /// </summary>
118+ private static void OnReceived ( object sender , DataReceivedEventArgs e )
92119 {
93- return Mathf . Floor ( value / multiple ) * multiple ;
120+ var message = e . Data ;
121+
122+ // ファイルに変更があった場合もしくは
123+ // ファイルの名前が変更されたらコンパイルフラグを立てます
124+ //
125+ // この関数では AssetDatabase.Refresh を呼び出しても何も起きないので
126+ // フラグだけ立てておいて Refresh は EditorApplication.update で行います
127+ if ( message . Contains ( "OnChanged" ) || message . Contains ( "OnRenamed" ) )
128+ {
129+ m_isRefresh = true ;
130+ }
94131 }
95132 }
96- }
133+ }
134+
0 commit comments