@@ -35,6 +35,8 @@ public class ModelExporter : System.IDisposable
35
35
36
36
const string FileBaseName = "Untitled" ;
37
37
38
+ const string ProgressBarTitle = "Fbx Export" ;
39
+
38
40
/// <summary>
39
41
/// Create instance of example
40
42
/// </summary>
@@ -249,12 +251,23 @@ protected void ExportTransform (UnityEngine.Transform unityTransform, FbxNode fb
249
251
/// <summary>
250
252
/// Unconditionally export components on this game object
251
253
/// </summary>
252
- protected void ExportComponents ( GameObject unityGo , FbxScene fbxScene , FbxNode fbxNodeParent )
254
+ protected int ExportComponents ( GameObject unityGo , FbxScene fbxScene , FbxNode fbxNodeParent , int currentIndex , int objectCount )
253
255
{
256
+ int i = currentIndex ;
257
+
254
258
// create an FbxNode and add it as a child of parent
255
259
FbxNode fbxNode = FbxNode . Create ( fbxScene , unityGo . name ) ;
256
260
NumNodes ++ ;
257
261
262
+ i ++ ;
263
+ if ( EditorUtility . DisplayCancelableProgressBar (
264
+ ProgressBarTitle ,
265
+ string . Format ( "Creating FbxNode {0}/{1}" , i , objectCount ) ,
266
+ ( i / ( float ) objectCount ) * 0.5f ) ) {
267
+ // cancel silently
268
+ return - 1 ;
269
+ }
270
+
258
271
ExportTransform ( unityGo . transform , fbxNode ) ;
259
272
ExportMesh ( GetMeshInfo ( unityGo ) , fbxNode , fbxScene ) ;
260
273
@@ -266,10 +279,27 @@ protected void ExportComponents (GameObject unityGo, FbxScene fbxScene, FbxNode
266
279
// now unityGo through our children and recurse
267
280
foreach ( Transform childT in unityGo . transform )
268
281
{
269
- ExportComponents ( childT . gameObject , fbxScene , fbxNode ) ;
282
+ i = ExportComponents ( childT . gameObject , fbxScene , fbxNode , i , objectCount ) ;
270
283
}
284
+ return i ;
285
+ }
271
286
272
- return ;
287
+ /// <summary>
288
+ /// A count of how many GameObjects we are exporting, to have a rough
289
+ /// idea of how long creating the scene will take.
290
+ /// </summary>
291
+ /// <returns>The object count.</returns>
292
+ /// <param name="exportSet">Export set.</param>
293
+ public int GetGameObjectCount ( IEnumerable < UnityEngine . Object > exportSet )
294
+ {
295
+ int count = 0 ;
296
+ foreach ( var obj in exportSet ) {
297
+ var unityGo = GetGameObject ( obj ) ;
298
+ if ( unityGo ) {
299
+ count += unityGo . transform . hierarchyCount ;
300
+ }
301
+ }
302
+ return count ;
273
303
}
274
304
275
305
/// <summary>
@@ -279,73 +309,98 @@ protected void ExportComponents (GameObject unityGo, FbxScene fbxScene, FbxNode
279
309
public int ExportAll ( IEnumerable < UnityEngine . Object > unityExportSet )
280
310
{
281
311
Verbose = true ;
282
-
283
- // Create the FBX manager
284
- using ( var fbxManager = FbxManager . Create ( ) )
285
- {
286
- // Configure fbx IO settings.
287
- fbxManager . SetIOSettings ( FbxIOSettings . Create ( fbxManager , Globals . IOSROOT ) ) ;
288
-
289
- // Export texture as embedded
290
- fbxManager . GetIOSettings ( ) . SetBoolProp ( Globals . EXP_FBX_EMBEDDED , true ) ;
291
-
292
- // Create the exporter
293
- var fbxExporter = FbxExporter . Create ( fbxManager , "Exporter" ) ;
294
-
295
- // Initialize the exporter.
296
- int fileFormat = fbxManager . GetIOPluginRegistry ( ) . FindWriterIDByDescription ( "FBX ascii (*.fbx)" ) ;
297
- bool status = fbxExporter . Initialize ( LastFilePath , fileFormat , fbxManager . GetIOSettings ( ) ) ;
298
- // Check that initialization of the fbxExporter was successful
299
- if ( ! status )
300
- return 0 ;
301
-
302
- // Set compatibility to 2014
303
- fbxExporter . SetFileExportVersion ( "FBX201400" ) ;
304
-
305
- // Create a scene
306
- var fbxScene = FbxScene . Create ( fbxManager , "Scene" ) ;
307
-
308
- // set up the scene info
309
- FbxDocumentInfo fbxSceneInfo = FbxDocumentInfo . Create ( fbxManager , "SceneInfo" ) ;
310
- fbxSceneInfo . mTitle = Title ;
311
- fbxSceneInfo . mSubject = Subject ;
312
- fbxSceneInfo . mAuthor = "Unity Technologies" ;
313
- fbxSceneInfo . mRevision = "1.0" ;
314
- fbxSceneInfo . mKeywords = Keywords ;
315
- fbxSceneInfo . mComment = Comments ;
316
- fbxScene . SetSceneInfo ( fbxSceneInfo ) ;
317
-
318
- // Set up the axes (Y up, Z forward, X to the right) and units (meters)
319
- var fbxSettings = fbxScene . GetGlobalSettings ( ) ;
320
- fbxSettings . SetSystemUnit ( FbxSystemUnit . m ) ;
321
-
322
- // The Unity axis system has Y up, Z forward, X to the right (left handed system with odd parity).
323
- // The Maya axis system has Y up, Z forward, X to the left (right handed system with odd parity).
324
- // We need to export right-handed for Maya because ConvertScene can't switch handedness:
325
- // https://forums.autodesk.com/t5/fbx-forum/get-confused-with-fbxaxissystem-convertscene/td-p/4265472
326
- fbxSettings . SetAxisSystem ( FbxAxisSystem . MayaYUp ) ;
327
-
328
- // export set of object
329
- FbxNode fbxRootNode = fbxScene . GetRootNode ( ) ;
330
- foreach ( var obj in unityExportSet )
312
+ try {
313
+ // Create the FBX manager
314
+ using ( var fbxManager = FbxManager . Create ( ) )
331
315
{
332
- var unityGo = GetGameObject ( obj ) ;
333
-
334
- if ( unityGo )
316
+ // Configure fbx IO settings.
317
+ fbxManager . SetIOSettings ( FbxIOSettings . Create ( fbxManager , Globals . IOSROOT ) ) ;
318
+
319
+ // Export texture as embedded
320
+ fbxManager . GetIOSettings ( ) . SetBoolProp ( Globals . EXP_FBX_EMBEDDED , true ) ;
321
+
322
+ // Create the exporter
323
+ var fbxExporter = FbxExporter . Create ( fbxManager , "Exporter" ) ;
324
+
325
+ // Initialize the exporter.
326
+ int fileFormat = fbxManager . GetIOPluginRegistry ( ) . FindWriterIDByDescription ( "FBX ascii (*.fbx)" ) ;
327
+ bool status = fbxExporter . Initialize ( LastFilePath , fileFormat , fbxManager . GetIOSettings ( ) ) ;
328
+ // Check that initialization of the fbxExporter was successful
329
+ if ( ! status )
330
+ return 0 ;
331
+
332
+ // Set compatibility to 2014
333
+ fbxExporter . SetFileExportVersion ( "FBX201400" ) ;
334
+
335
+ // Set the progress callback.
336
+ fbxExporter . SetProgressCallback ( ExportProgressCallback ) ;
337
+
338
+ // Create a scene
339
+ var fbxScene = FbxScene . Create ( fbxManager , "Scene" ) ;
340
+
341
+ // set up the scene info
342
+ FbxDocumentInfo fbxSceneInfo = FbxDocumentInfo . Create ( fbxManager , "SceneInfo" ) ;
343
+ fbxSceneInfo . mTitle = Title ;
344
+ fbxSceneInfo . mSubject = Subject ;
345
+ fbxSceneInfo . mAuthor = "Unity Technologies" ;
346
+ fbxSceneInfo . mRevision = "1.0" ;
347
+ fbxSceneInfo . mKeywords = Keywords ;
348
+ fbxSceneInfo . mComment = Comments ;
349
+ fbxScene . SetSceneInfo ( fbxSceneInfo ) ;
350
+
351
+ // Set up the axes (Y up, Z forward, X to the right) and units (meters)
352
+ var fbxSettings = fbxScene . GetGlobalSettings ( ) ;
353
+ fbxSettings . SetSystemUnit ( FbxSystemUnit . m ) ;
354
+
355
+ // The Unity axis system has Y up, Z forward, X to the right (left handed system with odd parity).
356
+ // The Maya axis system has Y up, Z forward, X to the left (right handed system with odd parity).
357
+ // We need to export right-handed for Maya because ConvertScene can't switch handedness:
358
+ // https://forums.autodesk.com/t5/fbx-forum/get-confused-with-fbxaxissystem-convertscene/td-p/4265472
359
+ fbxSettings . SetAxisSystem ( FbxAxisSystem . MayaYUp ) ;
360
+
361
+ // export set of object
362
+ FbxNode fbxRootNode = fbxScene . GetRootNode ( ) ;
363
+ int i = 0 ;
364
+ int count = GetGameObjectCount ( unityExportSet ) ;
365
+ foreach ( var obj in unityExportSet )
335
366
{
336
- this . ExportComponents ( unityGo , fbxScene , fbxRootNode ) ;
367
+ var unityGo = GetGameObject ( obj ) ;
368
+
369
+ if ( unityGo )
370
+ {
371
+ i = this . ExportComponents ( unityGo , fbxScene , fbxRootNode , i , count ) ;
372
+ if ( i < 0 ) {
373
+ Debug . LogWarning ( "Export Cancelled" ) ;
374
+ }
375
+ }
337
376
}
338
- }
339
377
340
- // Export the scene to the file.
341
- status = fbxExporter . Export ( fbxScene ) ;
378
+ // Export the scene to the file.
379
+ status = fbxExporter . Export ( fbxScene ) ;
342
380
343
- // cleanup
344
- fbxScene . Destroy ( ) ;
345
- fbxExporter . Destroy ( ) ;
381
+ // cleanup
382
+ fbxScene . Destroy ( ) ;
383
+ fbxExporter . Destroy ( ) ;
346
384
347
- return status == true ? NumNodes : 0 ;
385
+ return status == true ? NumNodes : 0 ;
386
+ }
348
387
}
388
+ finally {
389
+ // You must clear the progress bar when you're done,
390
+ // otherwise it never goes away and many actions in Unity
391
+ // are blocked (e.g. you can't quit).
392
+ EditorUtility . ClearProgressBar ( ) ;
393
+ }
394
+ }
395
+
396
+ static bool ExportProgressCallback ( float percentage , string status ) {
397
+ // Convert from percentage to [0,1].
398
+ // Then convert from that to [0.5,1] because the first half of
399
+ // the progress bar was for creating the scene.
400
+ var progress01 = 0.5f * ( 1f + ( percentage / 100.0f ) ) ;
401
+
402
+ // Unity says "true" for "cancel"; FBX wants "true" for "continue"
403
+ return ! EditorUtility . DisplayCancelableProgressBar ( ProgressBarTitle , "Exporting Scene..." , progress01 ) ;
349
404
}
350
405
351
406
//
0 commit comments