@@ -20,6 +20,8 @@ namespace UnityEditor.Perception.Randomization
2020{
2121 class RunInUnitySimulationWindow : EditorWindow
2222 {
23+ private const string m_SupportedGPUString = "Tesla" ;
24+
2325 string m_BuildDirectory ;
2426 string m_BuildZipPath ;
2527 SysParamDefinition [ ] m_SysParamDefinitions ;
@@ -38,6 +40,12 @@ class RunInUnitySimulationWindow : EditorWindow
3840 RunParameters m_RunParameters ;
3941 const string k_SupportedGPUString = "NVIDIA" ;
4042
43+ EnumField m_BuildTypeMenu ;
44+ VisualElement m_BuildSelectControls ;
45+ TextField m_BuildPathField ;
46+ TextField m_SelectedBuildPathTextField ;
47+ TextField m_BuildIdField ;
48+
4149 [ MenuItem ( "Window/Run in Unity Simulation" ) ]
4250 static void ShowWindow ( )
4351 {
@@ -87,6 +95,13 @@ void CreateEstablishingConnectionUI(Project.State state)
8795 }
8896 }
8997
98+ enum BuildIdKind
99+ {
100+ BuildPlayer ,
101+ ExistingBuildID ,
102+ ExistingBuildZip
103+ }
104+
90105 void CreateRunInUnitySimulationUI ( )
91106 {
92107 var root = rootVisualElement ;
@@ -147,9 +162,52 @@ void CreateRunInUnitySimulationUI()
147162 copyPrevRandomSeedButton . clicked += ( ) =>
148163 EditorGUIUtility . systemCopyBuffer = PlayerPrefs . GetString ( "SimWindow/prevRandomSeed" ) ;
149164
165+
166+ m_BuildTypeMenu = root . Q < EnumField > ( "build-type-menu" ) ;
167+ m_BuildTypeMenu . Init ( BuildIdKind . BuildPlayer ) ;
168+ m_BuildTypeMenu . RegisterValueChangedCallback ( evt => { UpdateBuildIdElements ( ( BuildIdKind ) evt . newValue ) ; } ) ;
169+
170+ m_BuildSelectControls = root . Q < VisualElement > ( "build-select-controls" ) ;
171+
172+ m_SelectedBuildPathTextField = root . Q < TextField > ( "selected-build-path" ) ;
173+ m_SelectedBuildPathTextField . isReadOnly = true ;
174+
175+ m_BuildPathField = root . Q < TextField > ( "selected-build-path" ) ;
176+ m_BuildIdField = root . Q < TextField > ( "build-id" ) ;
177+
178+ UpdateBuildIdElements ( ( BuildIdKind ) m_BuildTypeMenu . value ) ;
179+
180+ var selectBuildButton = root . Q < Button > ( "select-build-file-button" ) ;
181+ selectBuildButton . clicked += ( ) =>
182+ {
183+ var path = EditorUtility . OpenFilePanel ( "Select build ZIP file" , "" , "zip" ) ;
184+ if ( path . Length != 0 )
185+ {
186+ m_SelectedBuildPathTextField . value = path ;
187+ }
188+ } ;
150189 SetFieldsFromPlayerPreferences ( ) ;
151190 }
152191
192+ private void UpdateBuildIdElements ( BuildIdKind buildIdKind )
193+ {
194+ switch ( buildIdKind )
195+ {
196+ case BuildIdKind . ExistingBuildID :
197+ m_BuildSelectControls . SetEnabled ( false ) ;
198+ m_BuildIdField . SetEnabled ( true ) ;
199+ break ;
200+ case BuildIdKind . ExistingBuildZip :
201+ m_BuildSelectControls . SetEnabled ( true ) ;
202+ m_BuildIdField . SetEnabled ( false ) ;
203+ break ;
204+ case BuildIdKind . BuildPlayer :
205+ m_BuildSelectControls . SetEnabled ( false ) ;
206+ m_BuildIdField . SetEnabled ( false ) ;
207+ break ;
208+ }
209+ }
210+
153211 void SetFieldsFromPlayerPreferences ( )
154212 {
155213 m_RunNameField . value = IncrementRunName ( PlayerPrefs . GetString ( "SimWindow/runName" ) ) ;
@@ -217,16 +275,68 @@ async void RunInUnitySimulation()
217275 null ) ;
218276 try
219277 {
278+ m_RunButton . SetEnabled ( false ) ;
279+
280+ // Upload build
281+ var cancellationTokenSource = new CancellationTokenSource ( ) ;
282+ var token = cancellationTokenSource . Token ;
283+
220284 ValidateSettings ( ) ;
221- CreateLinuxBuildAndZip ( ) ;
222- await StartUnitySimulationRun ( runGuid ) ;
285+ string buildId = null ;
286+ var buildIdKind = ( BuildIdKind ) m_BuildTypeMenu . value ;
287+ switch ( buildIdKind )
288+ {
289+ case BuildIdKind . BuildPlayer :
290+ if ( CreateLinuxBuildAndZip ( ) )
291+ {
292+ buildId = await UploadBuild ( cancellationTokenSource , token ) ;
293+ }
294+ break ;
295+ case BuildIdKind . ExistingBuildZip :
296+ m_BuildZipPath = m_BuildPathField . value ;
297+ buildId = await UploadBuild ( cancellationTokenSource , token ) ;
298+ break ;
299+ case BuildIdKind . ExistingBuildID :
300+ buildId = m_BuildIdField . value ;
301+ break ;
302+ }
303+ if ( buildId == null )
304+ return ;
305+
306+ StartUnitySimulationRun ( runGuid , buildId ) ;
223307 }
224308 catch ( Exception e )
225309 {
226- EditorUtility . ClearProgressBar ( ) ;
227310 PerceptionEditorAnalytics . ReportRunInUnitySimulationFailed ( runGuid , e . Message ) ;
228311 throw ;
229312 }
313+ finally
314+ {
315+ m_RunButton . SetEnabled ( true ) ;
316+ EditorUtility . ClearProgressBar ( ) ;
317+ }
318+ }
319+
320+ private async Task < string > UploadBuild ( CancellationTokenSource cancellationTokenSource , CancellationToken token )
321+ {
322+ var buildId = await API . UploadBuildAsync (
323+ m_RunParameters . runName ,
324+ m_BuildZipPath ,
325+ null , null ,
326+ cancellationTokenSource ,
327+ progress =>
328+ {
329+ EditorUtility . DisplayProgressBar (
330+ "Unity Simulation Run" , "Uploading build..." , progress * 0.90f ) ;
331+ } ) ;
332+ if ( token . IsCancellationRequested )
333+ {
334+ Debug . Log ( "The build upload process has been cancelled. Aborting Unity Simulation launch." ) ;
335+ EditorUtility . ClearProgressBar ( ) ;
336+ return null ;
337+ }
338+
339+ return buildId ;
230340 }
231341
232342 void ValidateSettings ( )
@@ -237,8 +347,6 @@ void ValidateSettings()
237347 throw new NotSupportedException ( "Invalid instance count specified" ) ;
238348 if ( m_RunParameters . totalIterations <= 0 )
239349 throw new NotSupportedException ( "Invalid total iteration count specified" ) ;
240- if ( string . IsNullOrEmpty ( m_RunParameters . currentOpenScenePath ) )
241- throw new MissingFieldException ( "Invalid scene path" ) ;
242350 if ( m_RunParameters . currentScenario == null )
243351 throw new MissingFieldException (
244352 "There is not a Unity Simulation compatible scenario present in the scene" ) ;
@@ -250,16 +358,54 @@ void ValidateSettings()
250358 Path . GetExtension ( m_RunParameters . scenarioConfigAssetPath ) != ".json" )
251359 throw new NotSupportedException (
252360 "Scenario configuration must be a JSON text asset" ) ;
361+
362+ if ( ( ( BuildIdKind ) m_BuildTypeMenu . value ) == BuildIdKind . ExistingBuildZip &&
363+ ! File . Exists ( m_SelectedBuildPathTextField . value ) )
364+ {
365+ throw new NotSupportedException (
366+ "Selected build path does not exist" ) ;
367+ }
368+ if ( ( ( BuildIdKind ) m_BuildTypeMenu . value ) == BuildIdKind . ExistingBuildID &&
369+ String . IsNullOrEmpty ( m_BuildIdField . value ) )
370+ {
371+ throw new NotSupportedException ( "Empty Build ID" ) ;
372+ }
253373 }
254374
255- void CreateLinuxBuildAndZip ( )
375+ bool CreateLinuxBuildAndZip ( )
256376 {
377+ List < string > scenes = new List < string > ( ) ;
378+ foreach ( var scene in EditorBuildSettings . scenes )
379+ {
380+ if ( scene . enabled )
381+ scenes . Add ( scene . path ) ;
382+ }
383+
384+ if ( scenes . Count == 0 )
385+ {
386+ if ( EditorUtility . DisplayDialog ( "No Scenes Found" , "Could not find any enabled Scenes in build settings. Open File -> Build Settings and add all your required Scenes." , "Use Currently Open Scene" , "Cancel Build" ) )
387+ {
388+ var currentOpenScenePath = SceneManager . GetSceneAt ( 0 ) . path ;
389+ if ( string . IsNullOrEmpty ( currentOpenScenePath ) )
390+ {
391+ EditorUtility . DisplayDialog ( "Build Failed" , "Could not find an active Scene." , "OK" ) ;
392+ throw new Exception ( $ "Could not find an active Scene.") ;
393+ }
394+ scenes . Add ( currentOpenScenePath ) ;
395+ }
396+ else
397+ {
398+ return false ;
399+ }
400+ }
401+
257402 var projectBuildDirectory = $ "{ m_BuildDirectory } /{ m_RunParameters . runName } ";
258403 if ( ! Directory . Exists ( projectBuildDirectory ) )
259404 Directory . CreateDirectory ( projectBuildDirectory ) ;
405+
260406 var buildPlayerOptions = new BuildPlayerOptions
261407 {
262- scenes = new [ ] { m_RunParameters . currentOpenScenePath } ,
408+ scenes = scenes . ToArray ( ) ,
263409 locationPathName = Path . Combine ( projectBuildDirectory , $ "{ m_RunParameters . runName } .x86_64") ,
264410#if PLATFORM_CLOUD_RENDERING
265411 target = BuildTarget . CloudRendering ,
@@ -275,6 +421,8 @@ void CreateLinuxBuildAndZip()
275421 EditorUtility . DisplayProgressBar ( "Unity Simulation Run" , "Zipping Linux build..." , 0f ) ;
276422 Zip . DirectoryContents ( projectBuildDirectory , m_RunParameters . runName ) ;
277423 m_BuildZipPath = projectBuildDirectory + ".zip" ;
424+
425+ return true ;
278426 }
279427
280428 List < AppParam > UploadAppParam ( )
@@ -301,30 +449,8 @@ List<AppParam> UploadAppParam()
301449 return appParamIds ;
302450 }
303451
304- async Task StartUnitySimulationRun ( Guid runGuid )
452+ void StartUnitySimulationRun ( Guid runGuid , string buildId )
305453 {
306- m_RunButton . SetEnabled ( false ) ;
307-
308- // Upload build
309- var cancellationTokenSource = new CancellationTokenSource ( ) ;
310- var token = cancellationTokenSource . Token ;
311- var buildId = await API . UploadBuildAsync (
312- m_RunParameters . runName ,
313- m_BuildZipPath ,
314- null , null ,
315- cancellationTokenSource ,
316- progress =>
317- {
318- EditorUtility . DisplayProgressBar (
319- "Unity Simulation Run" , "Uploading build..." , progress * 0.90f ) ;
320- } ) ;
321- if ( token . IsCancellationRequested )
322- {
323- Debug . Log ( "The build upload process has been cancelled. Aborting Unity Simulation launch." ) ;
324- EditorUtility . ClearProgressBar ( ) ;
325- return ;
326- }
327-
328454 // Generate and upload app-params
329455 EditorUtility . DisplayProgressBar ( "Unity Simulation Run" , "Uploading app-params..." , 0.90f ) ;
330456 var appParams = UploadAppParam ( ) ;
@@ -345,8 +471,6 @@ async Task StartUnitySimulationRun(Guid runGuid)
345471 run . Execute ( ) ;
346472
347473 // Cleanup
348- m_RunButton . SetEnabled ( true ) ;
349- EditorUtility . ClearProgressBar ( ) ;
350474 PerceptionEditorAnalytics . ReportRunInUnitySimulationSucceeded ( runGuid , run . executionId ) ;
351475
352476 // Set new Player Preferences
0 commit comments