/// <summary> /// Create a prefab from the imported hierarchy of game objects. /// This is the final output of an Editor glTF import. /// </summary> protected IEnumerator <GameObject> CreatePrefabEnum() { string basename = "scene.prefab"; if (!String.IsNullOrEmpty(_imported.Scene.name)) { basename = String.Format("{0}.prefab", GLTFUtils.cleanName(_imported.Scene.name)); } string dir = UnityPathUtil.GetProjectPath(_importPath); string path = Path.Combine(dir, basename); GameObject prefab = PrefabUtility.SaveAsPrefabAsset(_imported.Scene, path); // Make the prefab visible. // // Note: The model hierarchy is kept hidden during the glTF import // so that the user never sees the partially reconstructed // model. prefab.SetActive(true); // Note: base.Clear() removes imported game objects from // the scene and from memory, but does not remove imported // asset files from disk. base.Clear(); yield return(prefab); }
/// <summary> /// Constructor /// </summary> public EditorGltfImporter(string gltfPath, string importPath, ProgressCallback progressCallback = null) : base(new Uri(gltfPath), null, new EditorGltfImportCache(UnityPathUtil.GetProjectPath(importPath)), progressCallback) { _importPath = importPath; }
/// <summary> /// Create a prefab from the imported hierarchy of game objects. /// This is the final output of an Editor glTF import. /// </summary> protected IEnumerator <GameObject> CreatePrefabEnum() { string basename = "scene.prefab"; if (!String.IsNullOrEmpty(_imported.Scene.name)) { basename = String.Format("{0}.prefab", GLTFUtils.cleanName(_imported.Scene.name)); } string dir = UnityPathUtil.GetProjectPath(_importPath); string path = Path.Combine(dir, basename); GameObject prefab = PrefabUtility.SaveAsPrefabAsset(_imported.Scene, path); // Note: base.Clear() removes imported game objects from // the scene and from memory, but does not remove imported // asset files from disk. base.Clear(); yield return(prefab); }
/// <summary> /// Coroutine to import GLTF files with Piglet's EditorGltfImporter. /// The string value returned via the IEnumerator is the target directory /// for the current import, so that files from an aborted/canceled import /// can be easily cleaned up. /// </summary> private static IEnumerator <string> ImportCoroutine(List <string> gltfPaths, string baseImportDir) { foreach (string gltfPath in gltfPaths) { string gltfBasename = Path.GetFileName(gltfPath); string gltfBasenameNoExt = Path.GetFileNameWithoutExtension(gltfPath); bool abortImport = false; // callback for updating progress during glTF import void OnProgress(GltfImportStep type, int count, int total) { ProgressLog.Instance.OnImportProgress(type, count, total); abortImport = EditorUtility.DisplayCancelableProgressBar( $"Importing {gltfBasename}...", ProgressLog.Instance.GetProgressMessage(), (float)count / total); } string importPath = UnityPathUtil.NormalizePathSeparators( Path.Combine(baseImportDir, gltfBasenameNoExt)); string importProjectPath = UnityPathUtil.GetProjectPath(importPath); if ((Directory.Exists(importPath) || File.Exists(importPath)) && _pigletOptions.PromptBeforeOverwritingFiles) { if (!EditorUtility.DisplayDialog( "Warning!", $"Overwrite \"{importProjectPath}\"?", "OK", "Cancel")) { yield break; } FileUtil.DeleteFileOrDirectory(importPath); AssetDatabase.Refresh(); } GltfImportTask importTask = EditorGltfImporter.GetImportTask(gltfPath, importPath, _pigletOptions.ImportOptions); importTask.OnProgress = OnProgress; GameObject importedPrefab = null; importTask.OnCompleted = (prefab) => importedPrefab = prefab; // restart import timer at zero ProgressLog.Instance.StartImport(); while (true) { if (abortImport) { importTask.Abort(); EditorUtility.ClearProgressBar(); yield break; } try { if (!importTask.MoveNext()) { break; } } catch (Exception e) { Debug.LogException(e); EditorUtility.ClearProgressBar(); EditorUtility.DisplayDialog("Import Failed", String.Format("Import of {0} failed. " + "See Unity console log for details.", gltfBasename), "OK"); yield break; } yield return(importPath); } // Before modifying the selection, store a handle to // the transform of the currently selected game object (if any). Transform selectedTransform = Selection.activeTransform; // Select the prefab file in the Project Browser. if (_pigletOptions.SelectPrefabAfterImport) { Selection.activeObject = importedPrefab; yield return(importPath); } if (_pigletOptions.AddPrefabToScene) { // If we are currently in Prefab Mode, exit // back to the main scene hierarchy view. // // Note: Prefab Mode was introduced in Unity 2018.3. #if UNITY_2018_3_OR_NEWER if (StageUtility.GetCurrentStageHandle() != StageUtility.GetMainStageHandle()) { StageUtility.GoToMainStage(); } #endif GameObject instance = (GameObject)PrefabUtility .InstantiatePrefab(importedPrefab); // parent the prefab instance to the currently // selected GameObject (if any) if (selectedTransform != null) { instance.transform.parent = selectedTransform; } if (_pigletOptions.SelectPrefabInScene) { Selection.activeGameObject = instance; yield return(importPath); } } if (_pigletOptions.OpenPrefabAfterImport) { AssetDatabase.OpenAsset(importedPrefab); // Note: This is the best method I could find // for automatically centering the prefab in // the scene view. For further info, see // https://answers.unity.com/questions/813814/framing-objects-via-script-in-the-unity-editor.html SceneView.FrameLastActiveSceneView(); } EditorUtility.ClearProgressBar(); } }