Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Packages import support, VPM manifest standardization, cleanup #15

Merged
merged 5 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 100 additions & 22 deletions Packages/com.varneon.fbx-to-blender-importer/Editor/ImportWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -15,28 +17,34 @@ namespace Varneon.BlenderFBXImporter
/// </summary>
internal class ImportWindow : EditorWindow
{
List<FBXAsset> models = new List<FBXAsset>();
[SerializeField]
private Texture2D windowIcon;

ImportParameters importParameters = new ImportParameters(1f, true);
private List<FBXAsset> models = new List<FBXAsset>();

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<string, bool> TryAddModelPathFunc;
private Action handleDragAndDrop;

private Func<string, bool> 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;
Expand All @@ -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;
}

Expand All @@ -83,19 +92,25 @@ private static bool DoesSelectionContainFBXAssets()
[MenuItem(MenuPath, false)]
private static void OpenImportPrompt()
{
ImportWindow window = GetWindow<ImportWindow>();
window.titleContent = new GUIContent("Blender FBX Importer", Resources.Load<Texture2D>("Icon_BlenderFBXImporter"));
window.minSize = MinWindowSize;
window.Show();
GetWindow<ImportWindow>();
}

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()
Expand Down Expand Up @@ -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;
}
Expand All @@ -227,5 +242,68 @@ private void CopyBlenderFBXImportCode()
{
EditorGUIUtility.systemCopyBuffer = PythonOperatorGenerator.GetBlenderFBXImportPythonScript(models.Select(c => c.Path).ToArray(), false, importParameters);
}

/// <summary>
/// Converts full path to one relative to the project
/// </summary>
/// <param name="path">Full path pointing inside the project</param>
/// <returns>Path relative to the project</returns>
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;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Packages/com.varneon.fbx-to-blender-importer/package.json
Original file line number Diff line number Diff line change
@@ -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"
}