diff --git a/Packages/com.varneon.fbx-to-blender-importer/Editor/ImportWindow.cs b/Packages/com.varneon.fbx-to-blender-importer/Editor/ImportWindow.cs index d0490a2..ce41971 100644 --- a/Packages/com.varneon.fbx-to-blender-importer/Editor/ImportWindow.cs +++ b/Packages/com.varneon.fbx-to-blender-importer/Editor/ImportWindow.cs @@ -7,6 +7,8 @@ using UnityEngine; using Object = UnityEngine.Object; using DragAndDropState = Varneon.BlenderFBXImporter.DragAndDropHandler.DragAndDropState; +using UnityEditor.PackageManager.Requests; +using UnityEditor.PackageManager; namespace Varneon.BlenderFBXImporter { @@ -15,28 +17,34 @@ namespace Varneon.BlenderFBXImporter /// internal class ImportWindow : EditorWindow { - List models = new List(); + [SerializeField] + private Texture2D windowIcon; - ImportParameters importParameters = new ImportParameters(1f, true); + private List models = new List(); - Vector2 scrollPos = Vector2.zero; + private ImportParameters importParameters = new ImportParameters(1f, true); - float previewSize = 50; + private Vector2 scrollPos = Vector2.zero; - const string MenuPath = "Assets/Import FBX to Blender"; + private float previewSize = 50; - static readonly Vector2 MinWindowSize = new Vector2(512, 512); + private const string MenuPath = "Assets/Import FBX to Blender"; - DragAndDropState dragAndDropState; + private static readonly Vector2 MinWindowSize = new Vector2(512, 512); - Action handleDragAndDrop; + private DragAndDropState dragAndDropState; - Func TryAddModelPathFunc; + private Action handleDragAndDrop; + + private Func TryAddModelPathFunc; + + private static string ApplicationDataPath; + + private static UnityEditor.PackageManager.PackageInfo[] LocalPackages; private struct FBXAsset { internal string Path; - internal string RelativePath; internal GUIContent Content; internal Object Asset; internal int ID; @@ -53,13 +61,14 @@ internal enum PreviewStatus internal FBXAsset(string path) { - Path = path; - RelativePath = Path; - string appPath = Application.platform == RuntimePlatform.WindowsEditor ? Application.dataPath.Replace('/', '\\') : Application.dataPath; - RelativePath = RelativePath.Replace(appPath.Substring(0, appPath.IndexOf("Assets")), string.Empty); - Asset = AssetDatabase.LoadAssetAtPath(RelativePath, typeof(Object)); + Asset = AssetDatabase.LoadAssetAtPath(path, typeof(Object)); + + Path = System.IO.Path.GetFullPath(path); + Content = new GUIContent(Path, AssetPreview.GetAssetPreview(Asset)); + ID = Asset.GetInstanceID(); + Status = PreviewStatus.Loading; } @@ -83,19 +92,25 @@ private static bool DoesSelectionContainFBXAssets() [MenuItem(MenuPath, false)] private static void OpenImportPrompt() { - ImportWindow window = GetWindow(); - window.titleContent = new GUIContent("Blender FBX Importer", Resources.Load("Icon_BlenderFBXImporter")); - window.minSize = MinWindowSize; - window.Show(); + GetWindow(); } private void OnEnable() { - models.AddRange(GetSelectedFBXAssetPaths().Select(c => new FBXAsset(c))); + ApplicationDataPath = Application.dataPath.Replace('\\', '/'); + + titleContent = new GUIContent("Blender FBX Importer", windowIcon); + + minSize = MinWindowSize; TryAddModelPathFunc = path => TryAddModelPath(path); handleDragAndDrop = DragAndDropHandler.HandleFileDragAndDrop(dragAndDropState, TryAddModelPathFunc); + + foreach(string path in GetSelectedFBXAssetPaths()) + { + TryAddModelPath(path); + } } private void OnGUI() @@ -198,9 +213,9 @@ private bool TryAddModelPath(string path) { path = Path.GetFullPath(path); - if (models.Where(c => c.Path.Equals(path)).Count() == 0) + if (!models.Any(c => c.Path.Equals(path)) && TryConvertToRelativePath(path, out string relativePath)) { - models.Add(new FBXAsset(path)); + models.Add(new FBXAsset(relativePath)); return true; } @@ -227,5 +242,68 @@ private void CopyBlenderFBXImportCode() { EditorGUIUtility.systemCopyBuffer = PythonOperatorGenerator.GetBlenderFBXImportPythonScript(models.Select(c => c.Path).ToArray(), false, importParameters); } + + /// + /// Converts full path to one relative to the project + /// + /// Full path pointing inside the project + /// Path relative to the project + private static bool TryConvertToRelativePath(string path, out string relativePath) + { + // If string is null or empty, throw an exception + if (string.IsNullOrEmpty(path)) { throw new ArgumentException("Invalid path!", nameof(path)); } + + // If the directory is already valid, return original path + if (AssetDatabase.IsValidFolder(Path.GetDirectoryName(path))) { relativePath = path; return true; } + + // Get the project's root directory (Trim 'Assets' from the end of the path) + string projectDirectory = ApplicationDataPath.Substring(0, ApplicationDataPath.Length - 6); + + // Ensure that the path is the full path + path = Path.GetFullPath(path); + + // Replace backslashes with forward slashes + path = path.Replace('\\', '/'); + + // If path doesn't point inside the project, scan all packages + if (!path.StartsWith(projectDirectory)) + { + if(LocalPackages == null) + { + // Request all packages in offline mode + ListRequest request = Client.List(true, false); + + // Wait until the request is completed + while (!request.IsCompleted) { } + + if (request.Status == StatusCode.Success) + { + LocalPackages = request.Result.Where(p => p.source.Equals(PackageSource.Local)).ToArray(); + } + } + + // Try to find a package with same path as the one we are validating + UnityEditor.PackageManager.PackageInfo info = LocalPackages.FirstOrDefault(p => path.StartsWith(p.resolvedPath.Replace('\\', '/'))); + + // If a package with same path exists, return resolved path + if (info != null) + { + string resolvedPackagePath = info.resolvedPath.Replace('\\', '/'); + + relativePath = string.Concat("Packages/", info.name, path.Substring(resolvedPackagePath.Length)); + + return true; + } + + relativePath = string.Empty; + + return false; + } + + // Return a path relative to the project + relativePath = path.Replace(projectDirectory, string.Empty); + + return true; + } } } diff --git a/Packages/com.varneon.fbx-to-blender-importer/Editor/ImportWindow.cs.meta b/Packages/com.varneon.fbx-to-blender-importer/Editor/ImportWindow.cs.meta index fa1c9d6..9dcc36e 100644 --- a/Packages/com.varneon.fbx-to-blender-importer/Editor/ImportWindow.cs.meta +++ b/Packages/com.varneon.fbx-to-blender-importer/Editor/ImportWindow.cs.meta @@ -5,7 +5,9 @@ labels: MonoImporter: externalObjects: {} serializedVersion: 2 - defaultReferences: [] + defaultReferences: + - m_ViewDataDictionary: {instanceID: 0} + - windowIcon: {fileID: 2800000, guid: 03f16bc94a553d245b8b0d285528897d, type: 3} executionOrder: 0 icon: {fileID: 2800000, guid: 03f16bc94a553d245b8b0d285528897d, type: 3} userData: diff --git a/Packages/com.varneon.fbx-to-blender-importer/package.json b/Packages/com.varneon.fbx-to-blender-importer/package.json index b5147c5..148e36a 100644 --- a/Packages/com.varneon.fbx-to-blender-importer/package.json +++ b/Packages/com.varneon.fbx-to-blender-importer/package.json @@ -1,10 +1,12 @@ { "name": "com.varneon.fbx-to-blender-importer", - "version": "0.3.0", + "version": "0.3.1-beta.1", "displayName": "FBX To Blender Importer", "description": "Editor extension for importing FBX models from Unity into Blender using Python expressions", "author": { "name": "Varneon", "url": "https://github.com/Varneon" - } + }, + "unity": "2019.4", + "unityRelease": "29f1" } \ No newline at end of file