Skip to content

Commit 8506f1f

Browse files
author
Benoit Hudson
committed
UNI-22052 store save location as a relative path
1 parent 4e0d4d7 commit 8506f1f

File tree

2 files changed

+93
-40
lines changed

2 files changed

+93
-40
lines changed

Assets/FbxExporters/Editor/ConvertToModel.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,16 @@ static void OnContextItem (MenuCommand command)
7676
/// </summary>
7777
/// <returns>list of instanced Model Prefabs</returns>
7878
/// <param name="unityGameObjectsToConvert">Unity game objects to convert to Model Prefab instances</param>
79-
/// <param name="path">Path to save Model Prefab</param>
79+
/// <param name="path">Path to save Model Prefab; use FbxExportSettings if null</param>
8080
/// <param name="keepOriginal">If set to <c>true</c> keep original gameobject hierarchy.</param>
8181
public static GameObject[] CreateInstantiatedModelPrefab (GameObject [] unityGameObjectsToConvert, string path = null, bool keepOriginal = true)
8282
{
83+
if (path == null) {
84+
path = FbxExporters.EditorTools.ExportSettings.GetAbsoluteSavePath();
85+
} else {
86+
path = Path.GetFullPath(path);
87+
}
88+
8389
List<GameObject> result = new List<GameObject> ();
8490

8591
var exportSet = ModelExporter.RemoveRedundantObjects (unityGameObjectsToConvert);
@@ -90,8 +96,6 @@ public static GameObject[] CreateInstantiatedModelPrefab (GameObject [] unityGam
9096

9197
// find common ancestor root & filePath;
9298
string[] filePaths = new string[gosToExport.Length];
93-
if (path==null)
94-
path = FbxExporters.EditorTools.ExportSettings.instance.convertToModelSavePath;
9599

96100
for(int n = 0; n < gosToExport.Length; n++){
97101
var filename = ModelExporter.ConvertToValidFilename (gosToExport [n].name + ".fbx");

Assets/FbxExporters/Editor/FbxExportSettings.cs

Lines changed: 86 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -39,32 +39,35 @@ public override void OnInspectorGUI() {
3939
"Export objects centered around the union of the bounding box of selected objects"),
4040
exportSettings.centerObjects
4141
);
42-
42+
4343
GUILayout.BeginHorizontal ();
4444
GUILayout.Label (new GUIContent (
4545
"Export Path:",
4646
"Relative path for saving Model Prefabs."));
4747

48-
EditorGUILayout.SelectableLabel(GetRelativePath(exportSettings.convertToModelSavePath, Application.dataPath),
49-
EditorStyles.textField, GUILayout.MinWidth(SelectableLabelMinWidth), GUILayout.Height(EditorGUIUtility.singleLineHeight));
48+
var pathLabel = ExportSettings.GetRelativeSavePath();
49+
if (pathLabel == "./") { pathLabel = "(Assets root)"; }
50+
EditorGUILayout.SelectableLabel(pathLabel,
51+
EditorStyles.textField,
52+
GUILayout.MinWidth(SelectableLabelMinWidth),
53+
GUILayout.Height(EditorGUIUtility.singleLineHeight));
5054

5155
if (GUILayout.Button ("Browse", EditorStyles.miniButton, GUILayout.Width (BrowseButtonWidth))) {
52-
string initialPath = exportSettings.convertToModelSavePath;
53-
bool initialPathIsValid = true;
54-
if (string.IsNullOrEmpty(initialPath)) {
55-
initialPathIsValid = false;
56-
}
57-
string path = EditorUtility.OpenFolderPanel (
58-
"Select Model Prefabs Path", initialPathIsValid ? initialPath : Application.dataPath, null
59-
);
56+
string initialPath = ExportSettings.GetAbsoluteSavePath();
57+
string fullPath = EditorUtility.OpenFolderPanel (
58+
"Select Model Prefabs Path", initialPath, null
59+
);
6060

6161
// Unless the user canceled, make sure they chose something in the Assets folder.
62-
if (!string.IsNullOrEmpty (path)) {
63-
if(path.StartsWith (Application.dataPath)) {
64-
exportSettings.convertToModelSavePath = path;
65-
} else {
66-
Debug.LogWarning ("Please select a location in Assets/");
67-
}
62+
if (!string.IsNullOrEmpty (fullPath)) {
63+
var relativePath = GetRelativePath(Application.dataPath, fullPath);
64+
if (string.IsNullOrEmpty(relativePath)
65+
|| relativePath == ".."
66+
|| relativePath.StartsWith(".." + Path.DirectorySeparatorChar)) {
67+
Debug.LogWarning ("Please select a location in the Assets folder");
68+
} else {
69+
ExportSettings.SetRelativeSavePath(relativePath);
70+
}
6871
}
6972
}
7073

@@ -78,40 +81,86 @@ public override void OnInspectorGUI() {
7881
}
7982
}
8083

81-
private string GetRelativePath(string filePath, string folder){
82-
Uri pathUri;
83-
try{
84-
pathUri = new Uri (filePath);
85-
}
86-
catch(UriFormatException){
87-
return filePath;
88-
}
89-
if (!folder.EndsWith (Path.DirectorySeparatorChar.ToString ())) {
90-
folder += Path.DirectorySeparatorChar;
84+
private string GetRelativePath(string fromDir, string toDir) {
85+
// https://stackoverflow.com/questions/275689/how-to-get-relative-path-from-absolute-path
86+
// With fixes to handle that fromDir and toDir are both directories (not files).
87+
if (String.IsNullOrEmpty(fromDir)) throw new ArgumentNullException("fromDir");
88+
if (String.IsNullOrEmpty(toDir)) throw new ArgumentNullException("toDir");
89+
90+
// MakeRelativeUri assumes the path is a file unless it ends with a
91+
// path separator, so add one. Having multiple in a row is no problem.
92+
fromDir += Path.DirectorySeparatorChar;
93+
toDir += Path.DirectorySeparatorChar;
94+
95+
// Workaround for https://bugzilla.xamarin.com/show_bug.cgi?id=5921
96+
fromDir += Path.DirectorySeparatorChar;
97+
98+
Uri fromUri = new Uri(fromDir);
99+
Uri toUri = new Uri(toDir);
100+
101+
if (fromUri.Scheme != toUri.Scheme) { return null; } // path can't be made relative.
102+
103+
Uri relativeUri = fromUri.MakeRelativeUri(toUri);
104+
String relativePath = Uri.UnescapeDataString(relativeUri.ToString());
105+
106+
if (string.IsNullOrEmpty(relativePath)) {
107+
// The relative path is empty if it's the same directory.
108+
relativePath = "./";
91109
}
92-
Uri folderUri = new Uri (folder);
93-
string relativePath = Uri.UnescapeDataString (
94-
folderUri.MakeRelativeUri (pathUri).ToString ().Replace ('/', Path.DirectorySeparatorChar)
95-
);
96-
if (!relativePath.StartsWith ("Assets")) {
97-
relativePath = string.Format("Assets{0}{1}", Path.DirectorySeparatorChar, relativePath);
110+
111+
if (toUri.Scheme.Equals("file", StringComparison.InvariantCultureIgnoreCase)) {
112+
relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
98113
}
114+
99115
return relativePath;
100116
}
101117
}
102118

103119
[FilePath("ProjectSettings/FbxExportSettings.asset",FilePathAttribute.Location.ProjectFolder)]
104120
public class ExportSettings : FbxExporters.EditorTools.ScriptableSingleton<ExportSettings>
105121
{
122+
public const string kDefaultSavePath = "Objects";
123+
106124
public bool weldVertices = true;
107125
public bool embedTextures = false;
108126
public bool mayaCompatibleNames = true;
109127
public bool centerObjects = true;
110-
public string convertToModelSavePath;
111128

112-
void OnEnable()
113-
{
114-
convertToModelSavePath = Path.Combine (Application.dataPath, "Objects");
129+
/// <summary>
130+
/// The path where Convert To Model will save the new fbx and prefab.
131+
/// This is relative to the Application.dataPath
132+
/// </summary>
133+
[SerializeField]
134+
string convertToModelSavePath = kDefaultSavePath;
135+
136+
/// <summary>
137+
/// The path where Convert To Model will save the new fbx and prefab.
138+
/// This is relative to the Application.dataPath
139+
/// </summary>
140+
public static string GetRelativeSavePath() {
141+
var relativePath = instance.convertToModelSavePath;
142+
if (string.IsNullOrEmpty(relativePath)) {
143+
relativePath = kDefaultSavePath;
144+
}
145+
return relativePath;
146+
}
147+
148+
/// <summary>
149+
/// The path where Convert To Model will save the new fbx and prefab.
150+
/// This is an absolute path
151+
/// </summary>
152+
public static string GetAbsoluteSavePath() {
153+
var relativePath = GetRelativeSavePath();
154+
var absolutePath = Path.Combine(Application.dataPath, relativePath);
155+
return Path.GetFullPath(absolutePath);
156+
}
157+
158+
/// <summary>
159+
/// Set the path where Convert To Model will save the new fbx and prefab.
160+
/// This is interpreted as being relative to the Application.dataPath
161+
/// </summary>
162+
public static void SetRelativeSavePath(string newPath) {
163+
instance.convertToModelSavePath = newPath;
115164
}
116165

117166
[MenuItem("Edit/Project Settings/Fbx Export", priority = 300)]

0 commit comments

Comments
 (0)