@@ -74,33 +74,49 @@ private void OnGUI()
7474
7575 _isFrameworkInAnotherFolder = EditorGUILayout . Toggle ( new GUIContent ( "Not in Assets folder" , "If framework isn't in Assets directory, turn it on" ) , _isFrameworkInAnotherFolder ) ;
7676
77- if ( ! _isFrameworkInAnotherFolder ) GUI . enabled = false ;
77+ if ( ! _isFrameworkInAnotherFolder )
78+ {
79+ GUI . enabled = false ;
80+ GUI . backgroundColor = Color . white ;
81+ }
82+
83+ if ( _isFrameworkInAnotherFolder && string . IsNullOrEmpty ( _anotherFolderName ) ) GUI . backgroundColor = Color . red ;
7884
7985 _anotherFolderName = EditorGUILayout . TextField ( new GUIContent ( "Directory name" , "For example, if you throw this framework in Assets\\ MyImports\\ Frameworks, then write \" MyImports/Frameworks\" " ) , _anotherFolderName ) ;
8086
87+ GUI . backgroundColor = Color . white ;
88+
8189 if ( ! _isFrameworkInAnotherFolder ) GUI . enabled = true ;
8290
8391 EditorGUILayout . Space ( 10 ) ;
8492
8593 // Agents
8694 EditorGUILayout . LabelField ( "Agents" , EditorStyles . boldLabel ) ;
8795
96+ if ( _emotions . Count == 0 ) GUI . backgroundColor = Color . red ;
97+
8898 _emotionsReorderableList . DoLayoutList ( ) ;
8999
100+ GUI . backgroundColor = Color . white ;
101+
102+ if ( _requestTimeout == 0 ) GUI . backgroundColor = Color . red ;
103+
90104 _requestTimeout = EditorGUILayout . IntField ( new GUIContent ( "Request timeout(secs)" , "Timeout for requests to local TTS Python sever" ) , _requestTimeout ) ;
91105
106+ GUI . backgroundColor = Color . white ;
107+
92108 EditorGUILayout . Space ( 10 ) ;
93109
94110 // Python
95111 EditorGUILayout . LabelField ( "Python" , EditorStyles . boldLabel ) ;
96112
97113 _enablePythonDebug = EditorGUILayout . Toggle ( new GUIContent ( "Enable Python debug" , "If framework isn't in Assets directory, turn it on" ) , _enablePythonDebug ) ;
98114
99- if ( ! _enablePythonDebug ) GUI . enabled = false ;
115+ if ( string . IsNullOrEmpty ( _absolutePathToMainPy ) ) GUI . backgroundColor = Color . red ;
100116
101117 _absolutePathToMainPy = EditorGUILayout . TextField ( new GUIContent ( "Absolute path to main.py" ) , _absolutePathToMainPy ) ;
102118
103- if ( ! _enablePythonDebug ) GUI . enabled = true ;
119+ GUI . backgroundColor = Color . white ;
104120
105121 EditorGUILayout . Space ( 10 ) ;
106122
@@ -122,13 +138,43 @@ private void OnGUI()
122138 _ => LogLevel . All
123139 } ;
124140
141+ if ( _emotions . Count == 0 || _emotions . Contains ( string . Empty ) )
142+ {
143+ LogUtils . LogError ( "[UnityNeuroSpeech] You need to add at least one emotion!" ) ;
144+ return ;
145+ }
146+
147+ if ( _requestTimeout == 0 )
148+ {
149+ LogUtils . LogError ( "[UnityNeuroSpeech] \" Request timeout\" field can't be empty!" ) ;
150+ return ;
151+ }
152+
153+ if ( string . IsNullOrEmpty ( _absolutePathToMainPy ) )
154+ {
155+ LogUtils . LogError ( "[UnityNeuroSpeech] You need to write absolute path to main.py!" ) ;
156+ return ;
157+ }
158+
159+ if ( ! File . Exists ( _absolutePathToMainPy ) )
160+ {
161+ LogUtils . LogError ( "[UnityNeuroSpeech] main.py doesn't exist in this path!" ) ;
162+ return ;
163+ }
164+
125165 string createAgentScriptContent , createAgentScriptPath ;
126166
127167 if ( _isFrameworkInAnotherFolder )
128168 {
129169 // If the framework is placed in another folder, we'll have to change paths in multiple places.
130170
131- // First, remove the old CreateAgent.cs and copy a template version.
171+ if ( string . IsNullOrEmpty ( _anotherFolderName ) )
172+ {
173+ LogUtils . LogError ( "[UnityNeuroSpeech] If you enabled \" Not in Assets folder\" , you need to write \" Directory name\" ?" ) ;
174+ return ;
175+ }
176+
177+ // Remove the old CreateAgent.cs and copy a template version.
132178 // Later, we’ll replace parts of it to fit the custom folder structure.
133179 AssetDatabase . DeleteAsset ( $ "Assets/{ _anotherFolderName } /UnityNeuroSpeech/Editor/CreateAgent.cs") ;
134180 AssetDatabase . CopyAsset ( $ "Assets/{ _anotherFolderName } /UnityNeuroSpeech/Editor/CreateAgentTemplate.cs", $ "Assets/{ _anotherFolderName } /UnityNeuroSpeech/Editor/CreateAgent.cs") ;
@@ -155,18 +201,12 @@ private void OnGUI()
155201 createAgentScriptContent = File . ReadAllText ( createAgentScriptPath ) ;
156202 }
157203
158- if ( _emotions . Count == 0 )
159- {
160- LogUtils . LogError ( "[UnityNeuroSpeech] You need to add at least one emotion!" ) ;
161- return ;
162- }
163-
164204 // Flatten all emotions into a single comma-separated string.
165205 var emotionsString = "" ;
166206 foreach ( var em in _emotions ) emotionsString += $ "<{ em } >, ";
167207
168208 // Replace the system prompt to explicitly instruct the model to use only these emotions.
169- // (Note: some smaller models might still mess up, even with strict prompts. )
209+ // (Note: some smaller models might still mess up, even with strict prompts)
170210 createAgentScriptContent = createAgentScriptContent . Replace ( "For example: <angry>, <happy>, <sad>, etc." , $ "You can only use these emotions: { emotionsString } . WRITE THEM ONLY LIKE I SAID.") ;
171211
172212 // Turn the template into a real editor window script.
@@ -179,17 +219,19 @@ private void OnGUI()
179219
180220 // Changing debug in Python
181221 string mainPyContent ;
222+
182223 mainPyContent = File . ReadAllText ( _absolutePathToMainPy ) ;
183224
184225 if ( _enablePythonDebug )
185226 {
186227 // If debug already enabled
187- if ( mainPyContent . Contains ( "# warnings.simplefilter(action='ignore', category=FutureWarning)" ) ) return ;
188-
189- mainPyContent = mainPyContent . Replace ( "warnings.simplefilter(action='ignore', category=FutureWarning" , "# warnings.simplefilter(action='ignore', category=FutureWarning)" ) ;
190- mainPyContent = mainPyContent . Replace ( "sys.stdout = open(os.devnull, 'w')" , "# sys.stdout = open(os.devnull, 'w')" ) ;
191- mainPyContent = mainPyContent . Replace ( "logging.disable(logging.CRITICAL)" , "# logging.disable(logging.CRITICAL)" ) ;
192- mainPyContent = mainPyContent . Replace ( "# print(f\" Python executable(for gebug): {sys.executable}\" )" , "print(f\" Python executable(for gebug): {sys.executable}\" )" ) ;
228+ if ( ! mainPyContent . Contains ( "# warnings.simplefilter(action='ignore', category=FutureWarning)" ) )
229+ {
230+ mainPyContent = mainPyContent . Replace ( "warnings.simplefilter(action='ignore', category=FutureWarning" , "# warnings.simplefilter(action='ignore', category=FutureWarning)" ) ;
231+ mainPyContent = mainPyContent . Replace ( "sys.stdout = open(os.devnull, 'w')" , "# sys.stdout = open(os.devnull, 'w')" ) ;
232+ mainPyContent = mainPyContent . Replace ( "logging.disable(logging.CRITICAL)" , "# logging.disable(logging.CRITICAL)" ) ;
233+ mainPyContent = mainPyContent . Replace ( "# print(f\" Python executable(for gebug): {sys.executable}\" )" , "print(f\" Python executable(for gebug): {sys.executable}\" )" ) ;
234+ }
193235 }
194236 else
195237 {
@@ -198,13 +240,17 @@ private void OnGUI()
198240 mainPyContent = mainPyContent . Replace ( "# logging.disable(logging.CRITICAL)" , "logging.disable(logging.CRITICAL)" ) ;
199241 mainPyContent = mainPyContent . Replace ( "print(f\" Python executable(for gebug): {sys.executable}\" )" , "# print(f\" Python executable(for gebug): {sys.executable}\" )" ) ;
200242 }
243+
201244 File . WriteAllText ( _absolutePathToMainPy , mainPyContent ) ;
202245
203246 // Save the settings into a JSON file(unreadable code moment)
204247 var data = new JsonData ( LogUtils . logLevel , string . IsNullOrEmpty ( _customOllamaURI ) ? "http://localhost:11434" : _customOllamaURI , string . IsNullOrEmpty ( _customTTSURI ) ? "http://localhost:7777" : _customTTSURI , _requestTimeout ) ;
205248
206249 var json = JsonUtility . ToJson ( data , true ) ;
207- File . WriteAllText ( "Assets/Resources/Settings/UnityNeuroSpeechSettings.json" , json ) ;
250+
251+ var dir = Application . dataPath + "/Resources/Settings" ;
252+ if ( ! Directory . Exists ( dir ) ) Directory . CreateDirectory ( dir ) ;
253+ File . WriteAllText ( Path . Combine ( dir , "UnityNeuroSpeechSettings.json" ) , json ) ;
208254
209255 AssetDatabase . SaveAssets ( ) ;
210256 AssetDatabase . Refresh ( ) ;
0 commit comments