Skip to content

Commit 46fac41

Browse files
committed
add prefab name and path options
- don't allow user to choose fbx and prefab names if exporting multiple prefabs at once
1 parent dc1a48d commit 46fac41

File tree

8 files changed

+226
-173
lines changed

8 files changed

+226
-173
lines changed

Assets/FbxExporters/Editor/ConvertToModel.cs

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,13 @@ public static EditorTools.ExportSettings ExportSettings {
7373
/// <param name="unityGameObjectsToConvert">Unity game objects to convert to Model Prefab instances</param>
7474
/// <param name="path">Path to save Model Prefab; use FbxExportSettings if null</param>
7575
public static GameObject[] CreateInstantiatedModelPrefab (
76-
GameObject [] unityGameObjectsToConvert,
77-
string directoryFullPath = null)
76+
GameObject [] unityGameObjectsToConvert)
7877
{
79-
if (directoryFullPath == null) {
80-
directoryFullPath = FbxExporters.EditorTools.ExportSettings.GetAbsoluteSavePath();
81-
} else {
82-
directoryFullPath = Path.GetFullPath(directoryFullPath);
83-
}
84-
8578
var toExport = ModelExporter.RemoveRedundantObjects (unityGameObjectsToConvert);
86-
var wasExported = new List<GameObject>();
87-
foreach(var go in toExport) {
88-
try {
89-
ConvertToPrefabEditorWindow.Init(go);
90-
wasExported.Add(go);
91-
} catch(System.Exception xcp) {
92-
Debug.LogException(xcp);
93-
}
94-
}
95-
return wasExported.ToArray();
79+
var wasExported = new GameObject[toExport.Count];
80+
toExport.CopyTo (wasExported);
81+
ConvertToPrefabEditorWindow.Init (wasExported);
82+
return wasExported;
9683
}
9784

9885
/// <summary>
@@ -114,8 +101,11 @@ public static GameObject[] CreateInstantiatedModelPrefab (
114101
/// export settings.</param>
115102
public static GameObject Convert (
116103
GameObject toConvert,
117-
string directoryFullPath = null,
118-
string fbxFullPath = null)
104+
string fbxDirectoryFullPath = null,
105+
string fbxFullPath = null,
106+
string prefabDirectoryFullPath = null,
107+
string prefabFullPath = null
108+
)
119109
{
120110
// Only create the prefab (no FBX export) if we have selected the root of a model prefab instance.
121111
// Children of model prefab instances will also have "model prefab instance"
@@ -142,23 +132,19 @@ public static GameObject Convert (
142132

143133
if (string.IsNullOrEmpty(fbxFullPath)) {
144134
// Generate a unique filename.
145-
if (string.IsNullOrEmpty (directoryFullPath)) {
146-
directoryFullPath = FbxExporters.EditorTools.ExportSettings.GetAbsoluteSavePath ();
135+
if (string.IsNullOrEmpty (fbxDirectoryFullPath)) {
136+
fbxDirectoryFullPath = FbxExporters.EditorTools.ExportSettings.GetFbxAbsoluteSavePath();
147137
} else {
148-
directoryFullPath = Path.GetFullPath (directoryFullPath);
138+
fbxDirectoryFullPath = Path.GetFullPath (fbxDirectoryFullPath);
149139
}
150140
var fbxBasename = ModelExporter.ConvertToValidFilename (toConvert.name + ".fbx");
151141

152-
fbxFullPath = Path.Combine (directoryFullPath, fbxBasename);
142+
fbxFullPath = Path.Combine (fbxDirectoryFullPath, fbxBasename);
153143
if (File.Exists (fbxFullPath)) {
154-
fbxFullPath = IncrementFileName (directoryFullPath, fbxFullPath);
144+
fbxFullPath = IncrementFileName (fbxDirectoryFullPath, fbxFullPath);
155145
}
156146
}
157-
var assetRelativePath = FbxExporters.EditorTools.ExportSettings.ConvertToAssetRelativePath(fbxFullPath);
158-
var projectRelativePath = "Assets/" + assetRelativePath;
159-
if (string.IsNullOrEmpty(assetRelativePath)) {
160-
throw new System.Exception("Path " + fbxFullPath + " must be in the Assets folder.");
161-
}
147+
var projectRelativePath = GetAssetRelativePath (fbxFullPath);
162148

163149
// Make sure that the object names in the hierarchy are unique.
164150
// The import back in to Unity would do this automatically but
@@ -184,12 +170,37 @@ public static GameObject Convert (
184170
// Copy the mesh/materials from the FBX
185171
UpdateFromSourceRecursive (toConvert, unityMainAsset);
186172

187-
SetupFbxPrefab (toConvert, unityMainAsset, projectRelativePath, fbxFullPath);
173+
if (string.IsNullOrEmpty(prefabFullPath)) {
174+
// Generate a unique filename.
175+
if (string.IsNullOrEmpty (prefabDirectoryFullPath)) {
176+
fbxDirectoryFullPath = FbxExporters.EditorTools.ExportSettings.GetPrefabAbsoluteSavePath();
177+
} else {
178+
fbxDirectoryFullPath = Path.GetFullPath (prefabDirectoryFullPath);
179+
}
180+
var prefabBasename = ModelExporter.ConvertToValidFilename (toConvert.name + ".prefab");
181+
182+
prefabFullPath = Path.Combine (prefabDirectoryFullPath, prefabBasename);
183+
if (File.Exists (prefabFullPath)) {
184+
prefabFullPath = IncrementFileName (prefabDirectoryFullPath, prefabFullPath);
185+
}
186+
}
187+
var prefabProjectRelativePath = GetAssetRelativePath (prefabFullPath);
188+
189+
SetupFbxPrefab (toConvert, unityMainAsset, prefabProjectRelativePath, fbxFullPath);
188190

189191
toConvert.name = Path.GetFileNameWithoutExtension (fbxFullPath);
190192
return toConvert;
191193
}
192194

195+
private static string GetAssetRelativePath(string fullPath){
196+
var assetRelativePath = FbxExporters.EditorTools.ExportSettings.ConvertToAssetRelativePath(fullPath);
197+
var projectRelativePath = "Assets/" + assetRelativePath;
198+
if (string.IsNullOrEmpty(assetRelativePath)) {
199+
throw new System.Exception("Path " + fullPath + " must be in the Assets folder.");
200+
}
201+
return projectRelativePath;
202+
}
203+
193204

194205
/// <summary>
195206
/// Create the prefab and connect it to the given fbx asset.

Assets/FbxExporters/Editor/ConvertToPrefabEditorWindow.cs

Lines changed: 78 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,22 @@ namespace Editor
1212
public class ConvertToPrefabEditorWindow : ExportOptionsEditorWindow
1313
{
1414
protected override GUIContent m_windowTitle { get { return new GUIContent ("Convert Options"); }}
15-
private GameObject m_toConvert;
15+
private GameObject[] m_toConvert;
16+
private string m_prefabFileName = "";
1617

17-
public static void Init (GameObject toConvert)
18+
public static void Init (GameObject[] toConvert)
1819
{
1920
ConvertToPrefabEditorWindow window = CreateWindow<ConvertToPrefabEditorWindow> ();
20-
window.InitializeWindow (filename: toConvert.name, singleHierarchyExport: true, exportType: ModelExporter.AnimationExportType.all);
21-
window.SetGameObjectToConvert (toConvert);
21+
window.InitializeWindow (filename: toConvert.Length >= 1? toConvert[0].name : "", singleHierarchyExport: true, exportType: ModelExporter.AnimationExportType.all);
22+
window.SetGameObjectsToConvert (toConvert);
2223
window.Show ();
2324
}
2425

25-
public void SetGameObjectToConvert(GameObject toConvert){
26+
public void SetGameObjectsToConvert(GameObject[] toConvert){
2627
m_toConvert = toConvert;
28+
if (toConvert.Length >= 1) {
29+
m_prefabFileName = toConvert [0].name;
30+
}
2731
}
2832

2933
protected override void OnEnable ()
@@ -42,35 +46,85 @@ protected override void OnEnable ()
4246

4347
protected override void Export ()
4448
{
45-
var filePath = ExportSettings.GetExportModelAbsoluteSavePath ();
49+
var fbxDirPath = ExportSettings.GetFbxAbsoluteSavePath ();
50+
var fbxPath = System.IO.Path.Combine (fbxDirPath, m_exportFileName + ".fbx");
4651

47-
filePath = System.IO.Path.Combine (filePath, m_exportFileName + ".fbx");
52+
var prefabDirPath = ExportSettings.GetPrefabAbsoluteSavePath ();
53+
var prefabPath = System.IO.Path.Combine (prefabDirPath, m_prefabFileName + ".prefab");
4854

4955
// check if file already exists, give a warning if it does
50-
if (System.IO.File.Exists (filePath)) {
51-
bool overwrite = UnityEditor.EditorUtility.DisplayDialog (
52-
string.Format("{0} Warning", ModelExporter.PACKAGE_UI_NAME),
53-
string.Format("File {0} already exists.", filePath),
54-
"Overwrite", "Cancel");
55-
if (!overwrite) {
56-
this.Close ();
57-
58-
if (GUI.changed) {
59-
SaveExportSettings ();
60-
}
61-
return;
62-
}
63-
}
56+
CheckFileExists (fbxPath);
57+
CheckFileExists (prefabPath);
6458

65-
if (!m_toConvert) {
59+
if (m_toConvert == null) {
6660
Debug.LogError ("FbxExporter: missing object for conversion");
6761
}
68-
ConvertToModel.Convert (m_toConvert, fbxFullPath: filePath);
62+
63+
if (m_toConvert.Length == 1) {
64+
ConvertToModel.Convert (m_toConvert[0], fbxFullPath: fbxPath, prefabFullPath: prefabPath);
65+
return;
66+
}
67+
68+
foreach (var go in m_toConvert) {
69+
ConvertToModel.Convert (go, fbxDirectoryFullPath: fbxDirPath, prefabDirectoryFullPath: prefabDirPath);
70+
}
71+
}
72+
73+
protected override bool DisableNameSelection ()
74+
{
75+
return m_toConvert.Length > 1;
6976
}
7077

7178
protected override void CreateCustomUI ()
7279
{
73-
base.CreateCustomUI ();
80+
GUILayout.BeginHorizontal ();
81+
EditorGUILayout.LabelField(new GUIContent(
82+
"Prefab Name:",
83+
"Filename to save prefab to."),GUILayout.Width(LabelWidth-FieldOffset));
84+
85+
EditorGUI.BeginDisabledGroup (DisableNameSelection());
86+
m_prefabFileName = EditorGUILayout.TextField (m_prefabFileName);
87+
m_prefabFileName = ModelExporter.ConvertToValidFilename (m_prefabFileName);
88+
EditorGUI.EndDisabledGroup ();
89+
GUILayout.EndHorizontal ();
90+
91+
GUILayout.BeginHorizontal();
92+
EditorGUILayout.LabelField(new GUIContent(
93+
"Prefab Path:",
94+
"Relative path for saving Linked Prefabs."),GUILayout.Width(LabelWidth - FieldOffset));
95+
96+
var pathLabels = ExportSettings.GetRelativePrefabSavePaths();
97+
98+
ExportSettings.instance.selectedPrefabPath = EditorGUILayout.Popup (ExportSettings.instance.selectedPrefabPath, pathLabels, GUILayout.MinWidth(SelectableLabelMinWidth));
99+
100+
if (GUILayout.Button(new GUIContent("...", "Browse to a new location to save prefab to"), EditorStyles.miniButton, GUILayout.Width(BrowseButtonWidth)))
101+
{
102+
string initialPath = Application.dataPath;
103+
104+
string fullPath = EditorUtility.OpenFolderPanel(
105+
"Select Linked Prefab Save Path", initialPath, null
106+
);
107+
108+
// Unless the user canceled, make sure they chose something in the Assets folder.
109+
if (!string.IsNullOrEmpty(fullPath))
110+
{
111+
var relativePath = ExportSettings.ConvertToAssetRelativePath(fullPath);
112+
if (string.IsNullOrEmpty(relativePath))
113+
{
114+
Debug.LogWarning("Please select a location in the Assets folder");
115+
}
116+
else
117+
{
118+
ExportSettings.AddPrefabSavePath(relativePath);
119+
120+
// Make sure focus is removed from the selectable label
121+
// otherwise it won't update
122+
GUIUtility.hotControl = 0;
123+
GUIUtility.keyboardControl = 0;
124+
}
125+
}
126+
}
127+
GUILayout.EndHorizontal();
74128
}
75129
}
76130
}

Assets/FbxExporters/Editor/ConvertToPrefabSettings.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,29 @@ public override void OnInspectorGUI ()
2727
exportSettings.exportFormat = (ExportModelSettingsSerialize.ExportFormat)EditorGUILayout.Popup((int)exportSettings.exportFormat, exportFormatOptions);
2828
GUILayout.EndHorizontal();
2929

30-
// always greyed out, show only to let user know what will happen
31-
EditorGUI.BeginDisabledGroup(true);
3230
GUILayout.BeginHorizontal();
3331
EditorGUILayout.LabelField(new GUIContent("Include", "Select whether to export models, animation or both."), GUILayout.Width(LabelWidth - FieldOffset));
32+
// always greyed out, show only to let user know what will happen
33+
EditorGUI.BeginDisabledGroup(true);
3434
EditorGUILayout.Popup(0, includeOptions);
35+
EditorGUI.EndDisabledGroup ();
3536
GUILayout.EndHorizontal();
3637

3738
GUILayout.BeginHorizontal();
3839
EditorGUILayout.LabelField(new GUIContent("LOD level", "Select which LOD to export."), GUILayout.Width(LabelWidth - FieldOffset));
40+
// always greyed out, show only to let user know what will happen
41+
EditorGUI.BeginDisabledGroup(true);
3942
EditorGUILayout.Popup(0, lodOptions);
43+
EditorGUI.EndDisabledGroup ();
4044
GUILayout.EndHorizontal();
4145

4246
GUILayout.BeginHorizontal();
4347
EditorGUILayout.LabelField(new GUIContent("Object(s) Position", "Select an option for exporting object's transform."), GUILayout.Width(LabelWidth - FieldOffset));
48+
// always greyed out, show only to let user know what will happen
49+
EditorGUI.BeginDisabledGroup(true);
4450
EditorGUILayout.Popup(0, objPositionOptions);
45-
GUILayout.EndHorizontal();
4651
EditorGUI.EndDisabledGroup ();
52+
GUILayout.EndHorizontal();
4753

4854
// TODO: add implementation for these options, grey out in the meantime
4955
EditorGUI.BeginDisabledGroup (true);

Assets/FbxExporters/Editor/ExportModelEditorWindow.cs

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ public abstract class ExportOptionsEditorWindow : EditorWindow
3434

3535
private bool m_showOptions;
3636

37-
private GUIStyle m_nameTextFieldStyle;
38-
private GUIStyle m_fbxExtLabelStyle;
39-
private float m_fbxExtLabelWidth;
37+
protected GUIStyle m_nameTextFieldStyle;
38+
protected GUIStyle m_fbxExtLabelStyle;
39+
protected float m_fbxExtLabelWidth;
4040

4141
protected virtual void OnEnable(){
4242
InitializeReceiver ();
@@ -124,6 +124,10 @@ public void OnPresetSelectionChanged()
124124
/// </summary>
125125
protected virtual void CreateCustomUI(){}
126126

127+
protected virtual bool DisableNameSelection(){
128+
return false;
129+
}
130+
127131
protected void OnGUI ()
128132
{
129133
// Increasing the label width so that none of the text gets cut off
@@ -147,6 +151,7 @@ protected void OnGUI ()
147151
"Export Name:",
148152
"Filename to save model to."),GUILayout.Width(LabelWidth-TextFieldAlignOffset));
149153

154+
EditorGUI.BeginDisabledGroup (DisableNameSelection());
150155
// Show the export name with an uneditable ".fbx" at the end
151156
//-------------------------------------
152157
EditorGUILayout.BeginVertical ();
@@ -163,16 +168,17 @@ protected void OnGUI ()
163168
EditorGUILayout.EndHorizontal();
164169
EditorGUILayout.EndVertical ();
165170
//-----------------------------------
171+
EditorGUI.EndDisabledGroup ();
166172
GUILayout.EndHorizontal ();
167173

168174
GUILayout.BeginHorizontal();
169175
EditorGUILayout.LabelField(new GUIContent(
170176
"Export Path:",
171177
"Relative path for saving Model Prefabs."),GUILayout.Width(LabelWidth - FieldOffset));
172178

173-
var pathLabels = ExportSettings.GetRelativeSavePaths();
179+
var pathLabels = ExportSettings.GetRelativeFbxSavePaths();
174180

175-
ExportSettings.instance.selectedExportModelPath = EditorGUILayout.Popup (ExportSettings.instance.selectedExportModelPath, pathLabels, GUILayout.MinWidth(SelectableLabelMinWidth));
181+
ExportSettings.instance.selectedFbxPath = EditorGUILayout.Popup (ExportSettings.instance.selectedFbxPath, pathLabels, GUILayout.MinWidth(SelectableLabelMinWidth));
176182

177183
if (GUILayout.Button(new GUIContent("...", "Browse to a new location to export to"), EditorStyles.miniButton, GUILayout.Width(BrowseButtonWidth)))
178184
{
@@ -192,7 +198,7 @@ protected void OnGUI ()
192198
}
193199
else
194200
{
195-
ExportSettings.AddExportModelSavePath(relativePath);
201+
ExportSettings.AddFbxSavePath(relativePath);
196202

197203
// Make sure focus is removed from the selectable label
198204
// otherwise it won't update
@@ -231,6 +237,23 @@ protected void OnGUI ()
231237
SaveExportSettings ();
232238
}
233239
}
240+
241+
protected void CheckFileExists(string filePath){
242+
// check if file already exists, give a warning if it does
243+
if (System.IO.File.Exists (filePath)) {
244+
bool overwrite = UnityEditor.EditorUtility.DisplayDialog (
245+
string.Format("{0} Warning", ModelExporter.PACKAGE_UI_NAME),
246+
string.Format("File {0} already exists.", filePath),
247+
"Overwrite", "Cancel");
248+
if (!overwrite) {
249+
this.Close ();
250+
251+
if (GUI.changed) {
252+
SaveExportSettings ();
253+
}
254+
}
255+
}
256+
}
234257
}
235258

236259
public class ExportModelEditorWindow : ExportOptionsEditorWindow
@@ -258,25 +281,11 @@ protected override void OnEnable ()
258281
}
259282

260283
protected override void Export(){
261-
var filePath = ExportSettings.GetExportModelAbsoluteSavePath ();
284+
var filePath = ExportSettings.GetFbxAbsoluteSavePath ();
262285

263286
filePath = System.IO.Path.Combine (filePath, m_exportFileName + ".fbx");
264287

265-
// check if file already exists, give a warning if it does
266-
if (System.IO.File.Exists (filePath)) {
267-
bool overwrite = UnityEditor.EditorUtility.DisplayDialog (
268-
string.Format("{0} Warning", ModelExporter.PACKAGE_UI_NAME),
269-
string.Format("File {0} already exists.", filePath),
270-
"Overwrite", "Cancel");
271-
if (!overwrite) {
272-
this.Close ();
273-
274-
if (GUI.changed) {
275-
SaveExportSettings ();
276-
}
277-
return;
278-
}
279-
}
288+
CheckFileExists (filePath);
280289

281290
if (ModelExporter.ExportObjects (filePath, exportType: m_animExportType, lodExportType: ExportSettings.GetLODExportType()) != null) {
282291
// refresh the asset database so that the file appears in the

0 commit comments

Comments
 (0)