Skip to content

Commit 3b04322

Browse files
authored
UT-1945 Import Settings Reset Fix (#531)
Add extra export option to preserve import settings and add methods to save metafile. Add unit test. Update image and docs.
1 parent 8fa1cd4 commit 3b04322

File tree

5 files changed

+130
-0
lines changed

5 files changed

+130
-0
lines changed

com.unity.formats.fbx/Documentation~/exporting.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ When exporting an FBX file, the following **Export Options** window opens, displ
218218
| __Animated Skinned Mesh__ | Check this option to export animation on objects with skinned meshes.<br/><br/>If unchecked, the FBX Exporter does not export animation on skinned meshes. |
219219
| __Compatible Naming__ | Check this option to control renaming the GameObject and Materials during export. <br/><br/>The FBX Exporter ensures compatible naming with Autodesk® Maya® and Autodesk® Maya LT™ to avoid unexpected name changes between Unity and Autodesk® Maya® and Autodesk® Maya LT™. During export the FBX Exporter replaces characters in Unity names as follows:<br/> - Replaces invalid characters with underscores ("\_"). Invalid characters are all non-alphanumeric characters, except for the colon (":").<br/> - Adds an underscore ("\_") to names that begin with a number.<br/> - Replaces diacritics. For example, replaces "é" with “e”.<br/><br/>**NOTE:** If you have a Material with a space in its name, the space is replaced with an underscore ("_"). This results in a new Material being created when it is imported. For example, the Material named "Default Material" is exported as "Default_Material" and is created as a new Material when it is imported. If you want the exported Material to match an existing Material in the scene, you must manually rename the Material before exporting. |
220220
| __Export Unrendered__ | Check this option to export meshes that either don't have a renderer component, or that have a disabled renderer component. For example, a simplified mesh used as a Mesh collider. |
221+
|__Preserve Import Settings__ | Check this option to preserve all import settings applied to an existing fbx that will be overwritten in the export. If the GameObject is being exported as a new fbx, the import settings will not be carried over.|
221222

222223
> **NOTE:** For FBX Model filenames, the FBX Exporter ensures that names do not contain invalid characters for the file system. The set of invalid characters may differ between file systems.
223224
37.7 KB
Loading

com.unity.formats.fbx/Editor/ExportModelSettings.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ public override void OnInspectorGUI ()
9595
exportSettings.SetExportUnredererd(EditorGUILayout.Toggle(exportSettings.ExportUnrendered));
9696
EditorGUI.EndDisabledGroup ();
9797
GUILayout.EndHorizontal ();
98+
99+
GUILayout.BeginHorizontal();
100+
EditorGUILayout.LabelField(new GUIContent("Preserve Import Settings for Existing FBX",
101+
"If checked, the import settings from the overwritten FBX will be carried over to the new version."), GUILayout.Width(LabelWidth - FieldOffset));
102+
exportSettings.SetPreserveImportSettings(EditorGUILayout.Toggle(exportSettings.PreserveImportSettings));
103+
GUILayout.EndHorizontal();
98104
}
99105
}
100106

@@ -107,6 +113,7 @@ internal interface IExportOptions {
107113
bool UseMayaCompatibleNames { get; }
108114
bool AllowSceneModification { get; }
109115
bool ExportUnrendered { get; }
116+
bool PreserveImportSettings { get; }
110117
Transform AnimationSource { get; }
111118
Transform AnimationDest { get; }
112119
}
@@ -152,6 +159,7 @@ internal abstract class ExportOptionsSettingsSerializeBase : IExportOptions
152159
public abstract ExportSettings.LODExportType LODExportType { get; }
153160
public abstract ExportSettings.ObjectPosition ObjectPosition { get; }
154161
public abstract bool ExportUnrendered { get; }
162+
public virtual bool PreserveImportSettings { get; }
155163
public abstract bool AllowSceneModification { get; }
156164
}
157165

@@ -166,6 +174,7 @@ internal class ExportModelSettingsSerialize : ExportOptionsSettingsSerializeBase
166174
private ExportSettings.ObjectPosition objectPosition = ExportSettings.ObjectPosition.LocalCentered;
167175
[SerializeField]
168176
private bool exportUnrendered = true;
177+
private bool preserveImportSettings = true;
169178

170179
public override ExportSettings.Include ModelAnimIncludeOption { get { return include; } }
171180
public void SetModelAnimIncludeOption(ExportSettings.Include include) { this.include = include; }
@@ -175,6 +184,8 @@ internal class ExportModelSettingsSerialize : ExportOptionsSettingsSerializeBase
175184
public void SetObjectPosition(ExportSettings.ObjectPosition objPos){ this.objectPosition = objPos; }
176185
public override bool ExportUnrendered { get { return exportUnrendered; } }
177186
public void SetExportUnredererd(bool exportUnrendered){ this.exportUnrendered = exportUnrendered; }
187+
public override bool PreserveImportSettings { get { return preserveImportSettings; } }
188+
public void SetPreserveImportSettings(bool preserveImportSettings){ this.preserveImportSettings = preserveImportSettings; }
178189
public override bool AllowSceneModification { get { return false; } }
179190
}
180191
}

com.unity.formats.fbx/Editor/FbxExporter.cs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3643,9 +3643,23 @@ internal int ExportAll (
36433643
Debug.LogWarning ("Export Cancelled");
36443644
return 0;
36453645
}
3646+
3647+
// make a temporary copy of the original metafile
3648+
string originalMetafilePath = "";
3649+
if (ExportOptions.PreserveImportSettings && File.Exists(m_lastFilePath))
3650+
{
3651+
originalMetafilePath = SaveMetafile();
3652+
}
3653+
36463654
// delete old file, move temp file
36473655
ReplaceFile();
36483656
AssetDatabase.Refresh();
3657+
3658+
// replace with original metafile if specified to
3659+
if (ExportOptions.PreserveImportSettings && originalMetafilePath != "")
3660+
{
3661+
ReplaceMetafile(originalMetafilePath);
3662+
}
36493663

36503664
return status == true ? NumNodes : 0;
36513665
}
@@ -3729,6 +3743,71 @@ private void ReplaceFile ()
37293743
}
37303744
}
37313745

3746+
private string SaveMetafile()
3747+
{
3748+
var tempMetafilePath = Path.GetTempFileName();
3749+
3750+
// Try as an absolute path
3751+
var fbxPath = m_lastFilePath;
3752+
if (AssetDatabase.LoadAssetAtPath(fbxPath, typeof(Object)) == null)
3753+
{
3754+
// Try as a relative path
3755+
fbxPath = "Assets" + m_lastFilePath.Substring(Application.dataPath.Length);
3756+
if (AssetDatabase.LoadAssetAtPath(fbxPath, typeof(Object)) == null)
3757+
{
3758+
Debug.LogWarning(string.Format("Failed to find a valid asset at {0}. Import settings will be reset to default values.", m_lastFilePath));
3759+
return "";
3760+
}
3761+
}
3762+
3763+
// get metafile for original fbx file
3764+
var metafile = fbxPath + ".meta";
3765+
3766+
#if UNITY_2019_1_OR_NEWER
3767+
metafile = VersionControl.Provider.GetAssetByPath(fbxPath).metaPath;
3768+
#endif
3769+
3770+
// save it to a temp file
3771+
try {
3772+
File.Copy(metafile, tempMetafilePath, true);
3773+
} catch(IOException) {
3774+
Debug.LogWarning (string.Format("Failed to copy file {0} to {1}. Import settings will be reset to default values.", metafile, tempMetafilePath));
3775+
return "";
3776+
}
3777+
3778+
return tempMetafilePath;
3779+
}
3780+
3781+
private void ReplaceMetafile(string metafilePath)
3782+
{
3783+
// Try as an absolute path
3784+
var fbxPath = m_lastFilePath;
3785+
if (AssetDatabase.LoadAssetAtPath(fbxPath, typeof(Object)) == null)
3786+
{
3787+
// Try as a relative path
3788+
fbxPath = "Assets" + m_lastFilePath.Substring(Application.dataPath.Length);
3789+
if (AssetDatabase.LoadAssetAtPath(fbxPath, typeof(Object)) == null)
3790+
{
3791+
Debug.LogWarning(string.Format("Failed to find a valid asset at {0}. Import settings will be reset to default values.", m_lastFilePath));
3792+
return;
3793+
}
3794+
}
3795+
3796+
// get metafile for new fbx file
3797+
var metafile = fbxPath + ".meta";
3798+
3799+
#if UNITY_2019_1_OR_NEWER
3800+
metafile = VersionControl.Provider.GetAssetByPath(fbxPath).metaPath;
3801+
#endif
3802+
3803+
// replace metafile with original one in temp file
3804+
try {
3805+
File.Copy(metafilePath, metafile, true);
3806+
} catch(IOException) {
3807+
Debug.LogWarning (string.Format("Failed to copy file {0} to {1}. Import settings will be reset to default values.", metafilePath, m_lastFilePath));
3808+
}
3809+
}
3810+
37323811
/// <summary>
37333812
/// GameObject/Export Selected Timeline Clip...
37343813
/// </summary>

com.unity.formats.fbx/Tests/FbxTests/ModelExporterTest.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,5 +1034,44 @@ private void CompareGameObjectChildren(GameObject obj, HashSet<string> expectedC
10341034
expectedChildren.Remove (child.name);
10351035
}
10361036
}
1037+
1038+
[Test]
1039+
public void TestPreserveImportSettings()
1040+
{
1041+
// create a primitive object and export to an fbx
1042+
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
1043+
var filename = GetRandomFbxFilePath();
1044+
ModelExporter.ExportObject(filename, cube);
1045+
1046+
// change an import setting
1047+
var importer = AssetImporter.GetAtPath(filename) as ModelImporter;
1048+
importer.importBlendShapes = !importer.importBlendShapes;
1049+
importer.SaveAndReimport();
1050+
1051+
// save original fbx's guid and import setting change
1052+
var originalGuid = AssetDatabase.AssetPathToGUID(filename);
1053+
var originalImportBlendShapes = importer.importBlendShapes;
1054+
1055+
// re-export with preserve import settings true and verify settings are the same
1056+
ModelExporter.ExportObjects(filename, new Object[] { cube });
1057+
importer.SaveAndReimport();
1058+
Assert.AreEqual(originalImportBlendShapes, importer.importBlendShapes);
1059+
1060+
// verify guids still match
1061+
var newGuid = AssetDatabase.AssetPathToGUID(filename);
1062+
Assert.AreEqual(originalGuid, newGuid);
1063+
1064+
// re-export with preserve import settings false and verify settings are different
1065+
var exportOptions = new ExportModelSettingsSerialize();
1066+
1067+
exportOptions.SetPreserveImportSettings(false);
1068+
ModelExporter.ExportObjects(filename, new Object[] { cube }, exportOptions);
1069+
importer.SaveAndReimport();
1070+
Assert.AreNotEqual(originalImportBlendShapes, importer.importBlendShapes);
1071+
1072+
// verify guids still match
1073+
newGuid = AssetDatabase.AssetPathToGUID(filename);
1074+
Assert.AreEqual(originalGuid, newGuid);
1075+
}
10371076
}
10381077
}

0 commit comments

Comments
 (0)