123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- using System.Collections.Generic;
- using UnityEngine;
- #if UNITY_2018_1_OR_NEWER
- using UnityEditor.Presets;
- #endif
- using System.Linq;
- using System.Security.Permissions;
- namespace UnityEditor.Formats.Fbx.Exporter
- {
- internal class ConvertToPrefabEditorWindow : ExportOptionsEditorWindow
- {
- protected override GUIContent WindowTitle { get { return new GUIContent("Convert Options"); } }
- protected override float MinWindowHeight { get { return 350; } } // determined by trial and error
- protected override string ExportButtonName { get { return "Convert"; } }
- private string m_prefabFileName = "";
- private float m_prefabExtLabelWidth;
- protected override bool DisableNameSelection
- {
- get
- {
- return (GetToExport() != null && GetToExport().Length > 1);
- }
- }
- protected override bool DisableTransferAnim
- {
- get
- {
- return GetToExport() == null || GetToExport().Length > 1;
- }
- }
- public static void Init(IEnumerable<GameObject> toConvert)
- {
- ConvertToPrefabEditorWindow window = CreateWindow<ConvertToPrefabEditorWindow>();
- window.InitializeWindow();
- window.SetGameObjectsToConvert(toConvert);
- window.Show();
- }
- protected void SetGameObjectsToConvert(IEnumerable<GameObject> toConvert)
- {
- SetToExport(toConvert.OrderBy(go => go.name).ToArray());
- TransferAnimationSource = null;
- TransferAnimationDest = null;
- string fbxFileName = null;
- if (GetToExport().Length == 1)
- {
- var go = ModelExporter.GetGameObject(GetToExport()[0]);
- // check if the GameObject is a model instance, use as default filename and path if it is
- GameObject mainAsset = ConvertToNestedPrefab.GetFbxAssetOrNull(go);
- if (!mainAsset)
- {
- // Use the game object's name
- m_prefabFileName = go.name;
- }
- else
- {
- // Use the asset's name
- var mainAssetRelPath = AssetDatabase.GetAssetPath(mainAsset);
- // remove Assets/ from beginning of path
- mainAssetRelPath = mainAssetRelPath.Substring("Assets".Length);
- m_prefabFileName = System.IO.Path.GetFileNameWithoutExtension(mainAssetRelPath);
- ExportSettings.AddFbxSavePath(System.IO.Path.GetDirectoryName(mainAssetRelPath));
- fbxFileName = m_prefabFileName;
- }
- var fullPrefabPath = System.IO.Path.Combine(ExportSettings.PrefabAbsoluteSavePath, m_prefabFileName + ".prefab");
- if (System.IO.File.Exists(fullPrefabPath))
- {
- m_prefabFileName = System.IO.Path.GetFileNameWithoutExtension(ConvertToNestedPrefab.IncrementFileName(ExportSettings.PrefabAbsoluteSavePath, m_prefabFileName + ".prefab"));
- }
- // if only one object selected, set transfer source/dest to this object
- if (go)
- {
- TransferAnimationSource = go.transform;
- TransferAnimationDest = go.transform;
- }
- }
- else if (GetToExport().Length > 1)
- {
- m_prefabFileName = "(automatic)";
- }
- // if there is an existing fbx file then use its name, otherwise use the same name as for the prefab
- this.SetFilename(fbxFileName != null? fbxFileName : m_prefabFileName);
- }
- protected override void OnEnable()
- {
- base.OnEnable();
- if (!InnerEditor)
- {
- InnerEditor = UnityEditor.Editor.CreateEditor(ExportSettings.instance.ConvertToPrefabSettings);
- }
- m_prefabExtLabelWidth = FbxExtLabelStyle.CalcSize(new GUIContent(".prefab")).x;
- }
- /// <summary>
- /// Return the number of objects in the selection that contain RectTransforms.
- /// </summary>
- protected int GetUIElementsInExportSetCount()
- {
- int count = 0;
- foreach (var obj in GetToExport())
- {
- var go = ModelExporter.GetGameObject(obj);
- var rectTransforms = go.GetComponentsInChildren<RectTransform>();
- count += rectTransforms.Length;
- }
- return count;
- }
- protected bool ExportSetContainsAnimation()
- {
- foreach (var obj in GetToExport())
- {
- var go = ModelExporter.GetGameObject(obj);
- if (go.GetComponentInChildren<Animation>() || go.GetComponentInChildren<Animator>())
- {
- return true;
- }
- }
- return false;
- }
- [SecurityPermission(SecurityAction.LinkDemand)]
- protected override bool Export()
- {
- if (string.IsNullOrEmpty(ExportFileName))
- {
- Debug.LogError("FbxExporter: Please specify an fbx filename");
- return false;
- }
- if (string.IsNullOrEmpty(m_prefabFileName))
- {
- Debug.LogError("FbxExporter: Please specify a prefab filename");
- return false;
- }
- var fbxDirPath = ExportSettings.FbxAbsoluteSavePath;
- var fbxPath = System.IO.Path.Combine(fbxDirPath, ExportFileName + ".fbx");
- var prefabDirPath = ExportSettings.PrefabAbsoluteSavePath;
- var prefabPath = System.IO.Path.Combine(prefabDirPath, m_prefabFileName + ".prefab");
- if (GetToExport() == null)
- {
- Debug.LogError("FbxExporter: missing object for conversion");
- return false;
- }
- int rectTransformCount = GetUIElementsInExportSetCount();
- if (rectTransformCount > 0)
- {
- // Warn that UI elements will break if converted
- string warning = string.Format("Warning: UI Components (ie, RectTransform) are not saved when converting to FBX.\n{0} item(s) in the selection will lose their UI components.",
- rectTransformCount);
- bool result = UnityEditor.EditorUtility.DisplayDialog(
- string.Format("{0} Warning", ModelExporter.PACKAGE_UI_NAME), warning, "Convert and Lose UI", "Cancel");
- if (!result)
- {
- return false;
- }
- }
- if (SettingsObject.UseMayaCompatibleNames && SettingsObject.AllowSceneModification)
- {
- string warning = "Names of objects in the hierarchy may change with the Compatible Naming option turned on";
- if (ExportSetContainsAnimation())
- {
- warning = "Compatible Naming option turned on. Names of objects in hierarchy may change and break animations.";
- }
- // give a warning dialog that indicates that names in the scene may change
- int result = UnityEditor.EditorUtility.DisplayDialogComplex(
- string.Format("{0} Warning", ModelExporter.PACKAGE_UI_NAME), warning, "OK", "Turn off and continue", "Cancel"
- );
- if (result == 1)
- {
- // turn compatible naming off
- SettingsObject.SetUseMayaCompatibleNames(false);
- }
- else if (result == 2)
- {
- return false;
- }
- }
- if (GetToExport().Length == 1)
- {
- var go = ModelExporter.GetGameObject(GetToExport()[0]);
- // Check if we'll be clobbering files. If so, warn the user
- // first and let them cancel out.
- if (!OverwriteExistingFile(prefabPath))
- {
- return false;
- }
- if (ConvertToNestedPrefab.WillExportFbx(go))
- {
- if (!OverwriteExistingFile(fbxPath))
- {
- return false;
- }
- }
- ConvertToNestedPrefab.Convert(
- go, fbxFullPath: fbxPath, prefabFullPath: prefabPath, exportOptions: ExportSettings.instance.ConvertToPrefabSettings.info
- );
- return true;
- }
- bool onlyPrefabAssets = ConvertToNestedPrefab.SetContainsOnlyPrefabAssets(GetToExport());
- int groupIndex = -1;
- // no need to undo if we aren't converting anything that's in the scene
- if (!onlyPrefabAssets)
- {
- Undo.IncrementCurrentGroup();
- groupIndex = Undo.GetCurrentGroup();
- Undo.SetCurrentGroupName(ConvertToNestedPrefab.UndoConversionCreateObject);
- }
- foreach (var obj in GetToExport())
- {
- // Convert, automatically choosing a file path that won't clobber any existing files.
- var go = ModelExporter.GetGameObject(obj);
- ConvertToNestedPrefab.Convert(
- go, fbxDirectoryFullPath: fbxDirPath, prefabDirectoryFullPath: prefabDirPath, exportOptions: ExportSettings.instance.ConvertToPrefabSettings.info
- );
- }
- if (!onlyPrefabAssets && groupIndex >= 0)
- {
- Undo.CollapseUndoOperations(groupIndex);
- Undo.IncrementCurrentGroup();
- }
- return true;
- }
- protected override ExportOptionsSettingsSerializeBase SettingsObject
- {
- get { return ExportSettings.instance.ConvertToPrefabSettings.info; }
- }
- #if UNITY_2018_1_OR_NEWER
- protected override void ShowPresetReceiver()
- {
- ShowPresetReceiver(ExportSettings.instance.ConvertToPrefabSettings);
- }
- #endif
- protected override void CreateCustomUI()
- {
- GUILayout.BeginHorizontal();
- EditorGUILayout.LabelField(new GUIContent(
- "Prefab Name",
- "Filename to save prefab to."), GUILayout.Width(LabelWidth - TextFieldAlignOffset));
- EditorGUI.BeginDisabledGroup(DisableNameSelection);
- // Show the export name with an uneditable ".prefab" at the end
- //-------------------------------------
- EditorGUILayout.BeginVertical();
- EditorGUILayout.BeginHorizontal(EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
- EditorGUI.indentLevel--;
- // continually resize to contents
- var textFieldSize = NameTextFieldStyle.CalcSize(new GUIContent(m_prefabFileName));
- m_prefabFileName = EditorGUILayout.TextField(m_prefabFileName, NameTextFieldStyle, GUILayout.Width(textFieldSize.x + 5), GUILayout.MinWidth(5));
- m_prefabFileName = ModelExporter.ConvertToValidFilename(m_prefabFileName);
- EditorGUILayout.LabelField("<color=#808080ff>.prefab</color>", FbxExtLabelStyle, GUILayout.Width(m_prefabExtLabelWidth));
- EditorGUI.indentLevel++;
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.EndVertical();
- //-----------------------------------
- EditorGUI.EndDisabledGroup();
- GUILayout.EndHorizontal();
- GUILayout.BeginHorizontal();
- EditorGUILayout.LabelField(new GUIContent(
- "Prefab Path",
- "Relative path for saving FBX Prefab Variants."), GUILayout.Width(LabelWidth - FieldOffset));
- var pathLabels = ExportSettings.GetRelativePrefabSavePaths();
- ExportSettings.instance.SelectedPrefabPath = EditorGUILayout.Popup(ExportSettings.instance.SelectedPrefabPath, pathLabels, GUILayout.MinWidth(SelectableLabelMinWidth));
- if (GUILayout.Button(new GUIContent("...", "Browse to a new location to save prefab to"), EditorStyles.miniButton, GUILayout.Width(BrowseButtonWidth)))
- {
- string initialPath = Application.dataPath;
- string fullPath = EditorUtility.OpenFolderPanel(
- "Select FBX Prefab Variant Save Path", initialPath, null
- );
- // Unless the user canceled, make sure they chose something in the Assets folder.
- if (!string.IsNullOrEmpty(fullPath))
- {
- var relativePath = ExportSettings.ConvertToAssetRelativePath(fullPath);
- if (string.IsNullOrEmpty(relativePath))
- {
- Debug.LogWarning("Please select a location in the Assets folder");
- }
- else
- {
- ExportSettings.AddPrefabSavePath(relativePath);
- // Make sure focus is removed from the selectable label
- // otherwise it won't update
- GUIUtility.hotControl = 0;
- GUIUtility.keyboardControl = 0;
- }
- }
- }
- GUILayout.EndHorizontal();
- }
- protected override void DoNotShowDialogUI()
- {
- EditorGUI.indentLevel--;
- ExportSettings.instance.ShowConvertToPrefabDialog = !EditorGUILayout.Toggle(
- new GUIContent("Don't ask me again", "Don't ask me again, use the last used paths and options instead"),
- !ExportSettings.instance.ShowConvertToPrefabDialog
- );
- }
- }
- }
|