Skip to content

Commit 4ee188d

Browse files
Add new features
- Add custom TTS URI - Add requestTimeout - Add enabling/disabling debug for Python
1 parent fc414ae commit 4ee188d

File tree

3 files changed

+84
-15
lines changed

3 files changed

+84
-15
lines changed

unity/Editor/BaseAgentController.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ internal sealed class BaseAgentController : MonoBehaviour, IAgent
6060
// TTS
6161
[Header("TTS")]
6262
[SerializeField] private AudioSource _responseAudioSource;
63+
private string _ttsURI;
64+
private int _requestTimeout;
6365

6466
// Ollama
6567
/// <summary>
@@ -85,6 +87,8 @@ private void Awake()
8587
var data = JsonUtility.FromJson<JsonData>(json);
8688
LogUtils.logLevel = data.logLevel;
8789
_ollamaURI = data.ollamaURI;
90+
_ttsURI = data.TTSURI;
91+
_requestTimeout = data.requestTimeout;
8892

8993
SafeExecutionUtils.SafeExecute("InitOllama", InitOllama, agentSettings.systemPrompt, agentSettings.modelName);
9094

@@ -204,12 +208,13 @@ private async void OnRecordStop(AudioChunk recordedAudio)
204208
private IEnumerator PostText(string text)
205209
{
206210
var bodyRaw = System.Text.Encoding.UTF8.GetBytes(text);
207-
using (var request = new UnityWebRequest("http://localhost:7777/tts", "POST"))
211+
using (var request = new UnityWebRequest(_ttsURI, "POST"))
208212
{
209213
request.uploadHandler = new UploadHandlerRaw(bodyRaw);
210-
request.downloadHandler = new DownloadHandlerAudioClip("http://localhost:7777/tts", AudioType.WAV);
214+
request.downloadHandler = new DownloadHandlerAudioClip(_ttsURI, AudioType.WAV);
211215
request.SetRequestHeader("Content-Type", "text/plain");
212216

217+
request.timeout = _requestTimeout;
213218
yield return request.SendWebRequest();
214219

215220
if (request.result != UnityWebRequest.Result.Success) LogUtils.LogError($"[UnityNeuroSpeech] TTS server probably is not running! Full error message: {request.error}");

unity/Editor/CreateSettings.cs

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,21 @@ internal sealed class CreateSettings : EditorWindow
1616
private bool _isFrameworkInAnotherFolder;
1717
private string _anotherFolderName;
1818

19+
// Custom URIs
20+
private string _customOllamaURI, _customTTSURI;
1921

22+
// Log level
2023
private int _selectedLogIndex;
2124
private string[] _logOptions = new[] { "None", "Error", "All" };
2225

23-
private string _customOllamaURI;
26+
// Request timeout
27+
private int _requestTimeout = 30;
2428

29+
// Python debug
30+
private bool _enablePythonDebug;
31+
private string _absolutePathToMainPy;
32+
33+
// Emotions
2534
private ReorderableList _emotionsReorderableList;
2635
private List<string> _emotions = new();
2736

@@ -58,22 +67,51 @@ private void OnEnable()
5867
}
5968
private void OnGUI()
6069
{
70+
// General
6171
EditorGUILayout.LabelField("General", EditorStyles.boldLabel);
72+
6273
_selectedLogIndex = EditorGUILayout.Popup("Logging type", _selectedLogIndex, _logOptions);
6374

75+
_isFrameworkInAnotherFolder = EditorGUILayout.Toggle(new GUIContent("Not in Assets folder", "If framework isn't in Assets directory, turn it on"), _isFrameworkInAnotherFolder);
76+
77+
if (!_isFrameworkInAnotherFolder) GUI.enabled = false;
78+
79+
_anotherFolderName = EditorGUILayout.TextField(new GUIContent("Directory name", "For example, if you throw this framework in Assets\\MyImports\\Frameworks, then write \"MyImports/Frameworks\""), _anotherFolderName);
80+
81+
if (!_isFrameworkInAnotherFolder) GUI.enabled = true;
82+
83+
EditorGUILayout.Space(10);
84+
85+
// Agents
86+
EditorGUILayout.LabelField("Agents", EditorStyles.boldLabel);
87+
6488
_emotionsReorderableList.DoLayoutList();
6589

66-
_isFrameworkInAnotherFolder = EditorGUILayout.Toggle(new GUIContent("Not in Assets folder", "If framework isn't in Assets directory, turn it on"), _isFrameworkInAnotherFolder);
90+
_requestTimeout = EditorGUILayout.IntField(new GUIContent("Request timeout(secs)", "Timeout for requests to local TTS Python sever"), _requestTimeout);
6791

68-
if (_isFrameworkInAnotherFolder)
69-
{
70-
_anotherFolderName = EditorGUILayout.TextField(new GUIContent("Directory name", "For example, if you throw this framework in Assets\\MyImports\\Frameworks, then write \"MyImports/Frameworks\""), _anotherFolderName);
71-
}
92+
EditorGUILayout.Space(10);
93+
94+
// Python
95+
EditorGUILayout.LabelField("Python", EditorStyles.boldLabel);
96+
97+
_enablePythonDebug = EditorGUILayout.Toggle(new GUIContent("Enable Python debug", "If framework isn't in Assets directory, turn it on"), _enablePythonDebug);
98+
99+
if (!_enablePythonDebug) GUI.enabled = false;
72100

101+
_absolutePathToMainPy = EditorGUILayout.TextField(new GUIContent("Absolute path to main.py"), _absolutePathToMainPy);
102+
103+
if (!_enablePythonDebug) GUI.enabled = true;
104+
105+
EditorGUILayout.Space(10);
106+
107+
// Advanced
73108
EditorGUILayout.LabelField("Advanced", EditorStyles.boldLabel);
74109

75110
_customOllamaURI = EditorGUILayout.TextField(new GUIContent("Custom Ollama URI", "If empty, Ollama URI will be default \"localhost:11434\""), _customOllamaURI);
76111

112+
_customTTSURI = EditorGUILayout.TextField(new GUIContent("Custom TTS URI", "If empty, TTS URI will be default \"localhost:7777\""), _customTTSURI);
113+
//
114+
77115
if (GUILayout.Button("Save"))
78116
{
79117
LogUtils.logLevel = _logOptions[_selectedLogIndex] switch
@@ -85,6 +123,7 @@ private void OnGUI()
85123
};
86124

87125
string createAgentScriptContent, createAgentScriptPath;
126+
88127
if (_isFrameworkInAnotherFolder)
89128
{
90129
// If the framework is placed in another folder, we'll have to change paths in multiple places.
@@ -98,7 +137,7 @@ private void OnGUI()
98137
createAgentScriptPath = Application.dataPath + $"/{_anotherFolderName}/UnityNeuroSpeech/Editor/CreateAgent.cs";
99138

100139
// Get the generated script content from disk.
101-
createAgentScriptContent = File.ReadAllText(Application.dataPath + $"/{_anotherFolderName}/UnityNeuroSpeech/Editor/CreateAgent.cs");
140+
createAgentScriptContent = File.ReadAllText(createAgentScriptPath);
102141

103142
// Replace asset paths inside the code to match the custom folder.
104143
createAgentScriptContent = createAgentScriptContent.Replace("UnityNeuroSpeech/Runtime", $"{_anotherFolderName}/UnityNeuroSpeech/Runtime");
@@ -113,7 +152,7 @@ private void OnGUI()
113152

114153
createAgentScriptPath = Application.dataPath + $"/UnityNeuroSpeech/Editor/CreateAgent.cs";
115154

116-
createAgentScriptContent = File.ReadAllText(Application.dataPath + $"/UnityNeuroSpeech/Editor/CreateAgent.cs");
155+
createAgentScriptContent = File.ReadAllText(createAgentScriptPath);
117156
}
118157

119158
if (_emotions.Count == 0)
@@ -138,8 +177,30 @@ private void OnGUI()
138177

139178
File.WriteAllText(createAgentScriptPath, createAgentScriptContent);
140179

141-
// Save the settings into a JSON file.
142-
var data = new JsonData(LogUtils.logLevel, string.IsNullOrEmpty(_customOllamaURI)? "http://localhost:11434" : _customOllamaURI);
180+
// Changing debug in Python
181+
string mainPyContent;
182+
mainPyContent = File.ReadAllText(_absolutePathToMainPy);
183+
184+
if (_enablePythonDebug)
185+
{
186+
// 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+
}
193+
else
194+
{
195+
mainPyContent = mainPyContent.Replace("# warnings.simplefilter(action='ignore', category=FutureWarning)", "warnings.simplefilter(action='ignore', category=FutureWarning");
196+
mainPyContent = mainPyContent.Replace("# sys.stdout = open(os.devnull, 'w')", "sys.stdout = open(os.devnull, 'w')");
197+
mainPyContent = mainPyContent.Replace("# logging.disable(logging.CRITICAL)", "logging.disable(logging.CRITICAL)");
198+
}
199+
File.WriteAllText(_absolutePathToMainPy, mainPyContent);
200+
201+
// Save the settings into a JSON file(unreadable code moment)
202+
var data = new JsonData(LogUtils.logLevel, string.IsNullOrEmpty(_customOllamaURI) ? "http://localhost:11434" : _customOllamaURI, string.IsNullOrEmpty(_customTTSURI) ? "http://localhost:7777" : _customTTSURI, _requestTimeout);
203+
143204
var json = JsonUtility.ToJson(data, true);
144205
File.WriteAllText("Assets/Resources/Settings/UnityNeuroSpeechSettings.json", json);
145206

unity/Shared/JsonData.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ namespace UnityNeuroSpeech.Shared
77
internal struct JsonData
88
{
99
public LogLevel logLevel;
10-
public string ollamaURI;
10+
public string ollamaURI, TTSURI;
11+
public int requestTimeout;
1112

12-
public JsonData(LogLevel logLevel, string ollamaURI)
13+
public JsonData(LogLevel logLevel, string ollamaURI, string TTSURI, int requestTimeout)
1314
{
1415
this.logLevel = logLevel;
1516
this.ollamaURI = ollamaURI;
16-
}
17+
this.TTSURI = TTSURI;
18+
this.requestTimeout = requestTimeout;
19+
}
1720
}
1821
}

0 commit comments

Comments
 (0)