Skip to content

Commit 0a50003

Browse files
authored
Merge pull request #1 from Unity-Technologies/UNI-20287-add-progress-bar
Uni 20287 add progress bar
2 parents 903f85b + 0e75020 commit 0a50003

File tree

1 file changed

+149
-62
lines changed

1 file changed

+149
-62
lines changed

Assets/Editor/FbxExporter.cs

Lines changed: 149 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class ModelExporter : System.IDisposable
3434

3535
const string FileBaseName = "Untitled";
3636

37+
const string ProgressBarTitle = "Fbx Export";
38+
3739
/// <summary>
3840
/// Create instance of example
3941
/// </summary>
@@ -248,12 +250,23 @@ protected void ExportTransform (UnityEngine.Transform unityTransform, FbxNode fb
248250
/// <summary>
249251
/// Unconditionally export components on this game object
250252
/// </summary>
251-
protected void ExportComponents (GameObject unityGo, FbxScene fbxScene, FbxNode fbxNodeParent)
253+
protected int ExportComponents (GameObject unityGo, FbxScene fbxScene, FbxNode fbxNodeParent, int currentIndex, int objectCount)
252254
{
255+
int i = currentIndex;
256+
253257
// create an FbxNode and add it as a child of parent
254258
FbxNode fbxNode = FbxNode.Create (fbxScene, unityGo.name);
255259
NumNodes++;
256260

261+
i++;
262+
if (EditorUtility.DisplayCancelableProgressBar(
263+
ProgressBarTitle,
264+
string.Format("Creating FbxNode {0}/{1}", i, objectCount),
265+
(i/(float)objectCount)*0.5f)) {
266+
// cancel silently
267+
return -1;
268+
}
269+
257270
ExportTransform ( unityGo.transform, fbxNode);
258271
ExportMesh (GetMeshInfo( unityGo ), fbxNode, fbxScene);
259272

@@ -265,10 +278,27 @@ protected void ExportComponents (GameObject unityGo, FbxScene fbxScene, FbxNode
265278
// now unityGo through our children and recurse
266279
foreach (Transform childT in unityGo.transform)
267280
{
268-
ExportComponents (childT.gameObject, fbxScene, fbxNode);
281+
i = ExportComponents (childT.gameObject, fbxScene, fbxNode, i, objectCount);
269282
}
283+
return i;
284+
}
270285

271-
return ;
286+
/// <summary>
287+
/// A count of how many GameObjects we are exporting, to have a rough
288+
/// idea of how long creating the scene will take.
289+
/// </summary>
290+
/// <returns>The object count.</returns>
291+
/// <param name="exportSet">Export set.</param>
292+
public int GetGameObjectCount(IEnumerable<UnityEngine.Object> exportSet)
293+
{
294+
int count = 0;
295+
foreach (var obj in exportSet) {
296+
var unityGo = GetGameObject (obj);
297+
if (unityGo) {
298+
count += unityGo.transform.hierarchyCount;
299+
}
300+
}
301+
return count;
272302
}
273303

274304
/// <summary>
@@ -278,72 +308,129 @@ protected void ExportComponents (GameObject unityGo, FbxScene fbxScene, FbxNode
278308
public int ExportAll (IEnumerable<UnityEngine.Object> unityExportSet)
279309
{
280310
Verbose = true;
281-
282-
// Create the FBX manager
283-
using (var fbxManager = FbxManager.Create ())
284-
{
285-
// Configure fbx IO settings.
286-
fbxManager.SetIOSettings (FbxIOSettings.Create (fbxManager, Globals.IOSROOT));
287-
288-
// Export texture as embedded
289-
fbxManager.GetIOSettings ().SetBoolProp (Globals.EXP_FBX_EMBEDDED, true);
290-
291-
// Create the exporter
292-
var fbxExporter = FbxExporter.Create (fbxManager, "Exporter");
293-
294-
// Initialize the exporter.
295-
int fileFormat = fbxManager.GetIOPluginRegistry ().FindWriterIDByDescription ("FBX ascii (*.fbx)");
296-
bool status = fbxExporter.Initialize (LastFilePath, fileFormat, fbxManager.GetIOSettings ());
297-
// Check that initialization of the fbxExporter was successful
298-
if (!status)
299-
return 0;
300-
301-
// Set compatibility to 2014
302-
fbxExporter.SetFileExportVersion("FBX201400");
303-
304-
// Create a scene
305-
var fbxScene = FbxScene.Create (fbxManager, "Scene");
306-
307-
// set up the scene info
308-
FbxDocumentInfo fbxSceneInfo = FbxDocumentInfo.Create (fbxManager, "SceneInfo");
309-
fbxSceneInfo.mTitle = Title;
310-
fbxSceneInfo.mSubject = Subject;
311-
fbxSceneInfo.mAuthor = "Unity Technologies";
312-
fbxSceneInfo.mRevision = "1.0";
313-
fbxSceneInfo.mKeywords = Keywords;
314-
fbxSceneInfo.mComment = Comments;
315-
fbxScene.SetSceneInfo (fbxSceneInfo);
316-
317-
// Set up the axes (Y up, Z forward, X to the right) and units (meters)
318-
var fbxSettings = fbxScene.GetGlobalSettings();
319-
fbxSettings.SetSystemUnit(FbxSystemUnit.m);
320-
321-
// The Unity axis system has Y up, Z forward, X to the right (left handed system with odd parity).
322-
// The Maya axis system has Y up, Z forward, X to the left (right handed system with odd parity).
323-
// We need to export right-handed for Maya because ConvertScene can't switch handedness:
324-
// https://forums.autodesk.com/t5/fbx-forum/get-confused-with-fbxaxissystem-convertscene/td-p/4265472
325-
fbxSettings.SetAxisSystem (FbxAxisSystem.MayaYUp);
326-
327-
// export set of object
328-
FbxNode fbxRootNode = fbxScene.GetRootNode ();
329-
foreach (var obj in unityExportSet)
311+
try{
312+
// Create the FBX manager
313+
using (var fbxManager = FbxManager.Create ())
330314
{
331-
var unityGo = GetGameObject (obj);
332-
333-
if ( unityGo )
315+
// Configure fbx IO settings.
316+
fbxManager.SetIOSettings (FbxIOSettings.Create (fbxManager, Globals.IOSROOT));
317+
318+
// Export texture as embedded
319+
fbxManager.GetIOSettings ().SetBoolProp (Globals.EXP_FBX_EMBEDDED, true);
320+
321+
// Create the exporter
322+
var fbxExporter = FbxExporter.Create (fbxManager, "Exporter");
323+
324+
// Initialize the exporter.
325+
int fileFormat = fbxManager.GetIOPluginRegistry ().FindWriterIDByDescription ("FBX ascii (*.fbx)");
326+
bool status = fbxExporter.Initialize (LastFilePath, fileFormat, fbxManager.GetIOSettings ());
327+
// Check that initialization of the fbxExporter was successful
328+
if (!status)
329+
return 0;
330+
331+
// Set compatibility to 2014
332+
fbxExporter.SetFileExportVersion("FBX201400");
333+
334+
// Set the progress callback.
335+
fbxExporter.SetProgressCallback(ExportProgressCallback);
336+
337+
// Create a scene
338+
var fbxScene = FbxScene.Create (fbxManager, "Scene");
339+
340+
// set up the scene info
341+
FbxDocumentInfo fbxSceneInfo = FbxDocumentInfo.Create (fbxManager, "SceneInfo");
342+
fbxSceneInfo.mTitle = Title;
343+
fbxSceneInfo.mSubject = Subject;
344+
fbxSceneInfo.mAuthor = "Unity Technologies";
345+
fbxSceneInfo.mRevision = "1.0";
346+
fbxSceneInfo.mKeywords = Keywords;
347+
fbxSceneInfo.mComment = Comments;
348+
fbxScene.SetSceneInfo (fbxSceneInfo);
349+
350+
// Set up the axes (Y up, Z forward, X to the right) and units (meters)
351+
var fbxSettings = fbxScene.GetGlobalSettings();
352+
fbxSettings.SetSystemUnit(FbxSystemUnit.m);
353+
354+
// The Unity axis system has Y up, Z forward, X to the right (left handed system with odd parity).
355+
// The Maya axis system has Y up, Z forward, X to the left (right handed system with odd parity).
356+
// We need to export right-handed for Maya because ConvertScene can't switch handedness:
357+
// https://forums.autodesk.com/t5/fbx-forum/get-confused-with-fbxaxissystem-convertscene/td-p/4265472
358+
fbxSettings.SetAxisSystem (FbxAxisSystem.MayaYUp);
359+
360+
// export set of object
361+
FbxNode fbxRootNode = fbxScene.GetRootNode ();
362+
int i = 0;
363+
int count = GetGameObjectCount(unityExportSet);
364+
foreach (var obj in unityExportSet)
334365
{
335-
this.ExportComponents ( unityGo, fbxScene, fbxRootNode);
366+
var unityGo = GetGameObject (obj);
367+
368+
if ( unityGo )
369+
{
370+
i = this.ExportComponents (unityGo, fbxScene, fbxRootNode, i, count);
371+
if(i < 0){
372+
Debug.LogWarning("Export Cancelled");
373+
return 0;
374+
}
375+
}
336376
}
377+
378+
// Export the scene to the file.
379+
status = fbxExporter.Export (fbxScene);
380+
381+
// cleanup
382+
fbxScene.Destroy ();
383+
fbxExporter.Destroy ();
384+
385+
if(exportCancelled){
386+
Debug.LogWarning ("Export Cancelled");
387+
// delete the file that got created
388+
EditorApplication.update += DeleteFile;
389+
return 0;
390+
}
391+
392+
return status == true ? NumNodes : 0;
337393
}
394+
}
395+
finally {
396+
// You must clear the progress bar when you're done,
397+
// otherwise it never goes away and many actions in Unity
398+
// are blocked (e.g. you can't quit).
399+
EditorUtility.ClearProgressBar();
400+
}
401+
}
402+
403+
static bool exportCancelled = false;
338404

339-
// Export the scene to the file.
340-
status = fbxExporter.Export (fbxScene);
405+
static bool ExportProgressCallback(float percentage, string status) {
406+
// Convert from percentage to [0,1].
407+
// Then convert from that to [0.5,1] because the first half of
408+
// the progress bar was for creating the scene.
409+
var progress01 = 0.5f * (1f + (percentage / 100.0f));
341410

342-
// cleanup
343-
fbxScene.Destroy ();
344-
fbxExporter.Destroy ();
411+
bool cancel = EditorUtility.DisplayCancelableProgressBar(ProgressBarTitle, "Exporting Scene...", progress01);
412+
413+
if (cancel) {
414+
exportCancelled = true;
415+
}
345416

346-
return status == true ? NumNodes : 0;
417+
// Unity says "true" for "cancel"; FBX wants "true" for "continue"
418+
return !cancel;
419+
}
420+
421+
static void DeleteFile()
422+
{
423+
if (File.Exists (LastFilePath)) {
424+
try {
425+
File.Delete (LastFilePath);
426+
} catch (IOException) {}
427+
428+
if (File.Exists (LastFilePath)) {
429+
Debug.LogWarning ("Failed to delete file: " + LastFilePath);
430+
}
431+
} else {
432+
EditorApplication.update -= DeleteFile;
433+
AssetDatabase.Refresh ();
347434
}
348435
}
349436

0 commit comments

Comments
 (0)