Merge pull request #1905 from mkc1370/feature/support_packages_directory

UnityPathでパッケージ管理下のファイルを扱えるように
This commit is contained in:
ousttrue
2022-11-09 13:27:07 +09:00
committed by GitHub
6 changed files with 152 additions and 54 deletions

View File

@@ -2,20 +2,27 @@ using System;
using System.IO;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.PackageManager;
using PackageInfo = UnityEditor.PackageManager.PackageInfo;
#endif
namespace UniGLTF
{
/// <summary>
/// relative path from Unity project root.
/// For AssetDatabase.
/// Manage paths that can be handled by AssetDatabase
/// Supports Assets or editable Package
///
/// note : Use '\' instead of '/' to delimit folders
/// </summary>
public struct UnityPath
{
#if UNITY_EDITOR
#region UnityPath
public string Value
{
get;
@@ -32,18 +39,66 @@ namespace UniGLTF
get { return Value == null; }
}
public bool IsUnderAssetsFolder
/// <summary>
/// If under Assets or under an editable Package return true
/// </summary>
public bool IsUnderWritableFolder
{
get
{
if (IsNull)
if (IsNull) return false;
if (PathType == PathType.Assets) return true;
if (PathType == PathType.Packages)
{
return false;
var split = Value.Split('/');
if (split.Length <= 1) return false;
var packageDirectory = $"{split[0]}/{split[1]}";
if (!Directory.Exists(packageDirectory)) return false;
var packageInfo = GetPackageInfo(packageDirectory);
if (packageInfo == null) return false;
// Local and Embedded packages are editable
if (packageInfo.source == PackageSource.Local
|| packageInfo.source == PackageSource.Embedded) return true;
}
return Value == "Assets" || Value.FastStartsWith("Assets/");
return false;
}
}
/// <summary>
/// Recursively check if path is included in local packages
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private static PackageInfo GetPackageInfo(string path)
{
if (string.IsNullOrWhiteSpace(path)) return null;
var packageInfo = PackageList.Find(x => x.resolvedPath == path || x.assetPath == path);
if (packageInfo != null)
{
return packageInfo;
}
return GetPackageInfo(Path.GetDirectoryName(path));
}
/// <summary>
/// List of packages loaded in unity
/// </summary>
private static readonly List<PackageInfo> PackageList
= AssetDatabase.FindAssets("package")
.Select(AssetDatabase.GUIDToAssetPath)
.Where(x => AssetDatabase.LoadAssetAtPath<TextAsset>(x) != null)
.Select(PackageInfo.FindForAssetPath)
.Where(x => x != null)
.ToList();
public bool IsStreamingAsset
{
get
@@ -92,6 +147,29 @@ namespace UniGLTF
return !string.IsNullOrEmpty(Value);
}
}
public PathType PathType
{
get
{
if (string.IsNullOrEmpty(Value)) return PathType.Unsuported;
var directory = Path.GetDirectoryName(Value);
if (string.IsNullOrEmpty(directory)) return PathType.Unsuported;
var rootDirectoryName = directory.Split(Path.DirectorySeparatorChar);
switch (rootDirectoryName[0])
{
case "Assets":
return PathType.Assets;
case "Packages":
return PathType.Packages;
default:
return PathType.Unsuported;
}
}
}
static readonly char[] EscapeChars = new char[]
{
@@ -127,7 +205,7 @@ namespace UniGLTF
}
else
{
return new UnityPath(Value + "/" + name);
return new UnityPath($"{Value}/{name}");
}
}
@@ -176,7 +254,7 @@ namespace UniGLTF
/// <returns></returns>
public UnityPath GetAssetFolder(string suffix)
{
if (!IsUnderAssetsFolder)
if (!IsUnderWritableFolder)
{
throw new NotImplementedException();
}
@@ -201,14 +279,14 @@ namespace UniGLTF
/// <returns></returns>
public static UnityPath FromUnityPath(string unityPath)
{
if (String.IsNullOrEmpty(unityPath))
if (String.IsNullOrEmpty(unityPath) || unityPath == ".")
{
return new UnityPath
{
Value = ""
};
}
return FromFullpath(Path.GetFullPath(unityPath));
return new UnityPath(unityPath);
}
#endregion
@@ -226,14 +304,6 @@ namespace UniGLTF
}
}
static string AssetFullPath
{
get
{
return BaseFullPath + "/Assets";
}
}
public string FullPath
{
get
@@ -242,7 +312,7 @@ namespace UniGLTF
{
throw new NotImplementedException();
}
return Path.Combine(BaseFullPath, Value).Replace("\\", "/");
return Path.GetFullPath(Value).Replace("\\", "/");
}
}
@@ -271,24 +341,24 @@ namespace UniGLTF
if (fullPath == BaseFullPath)
{
return new UnityPath
{
Value = ""
};
return new UnityPath("");
}
else if (fullPath.FastStartsWith(BaseFullPath + "/"))
if (fullPath.FastStartsWith($"{BaseFullPath}/Assets"))
{
return new UnityPath(fullPath.Substring(BaseFullPath.Length + 1));
}
else
{
return default(UnityPath);
}
}
public static bool IsUnderAssetFolder(string fullPath)
{
return fullPath.Replace("\\", "/").FastStartsWith(AssetFullPath);
var packageInfo = GetPackageInfo(fullPath);
if (packageInfo != null)
{
var packagePath = packageInfo.assetPath;
var fileName = fullPath.Substring(packageInfo.resolvedPath.Length + 1);
var relativePath = $"{packagePath}/{fileName}";
return new UnityPath(relativePath);
}
return default(UnityPath);
}
#endregion
@@ -336,7 +406,6 @@ namespace UniGLTF
}
}
#if UNITY_EDITOR
public T GetImporter<T>() where T : AssetImporter
{
return AssetImporter.GetAtPath(Value) as T;
@@ -354,7 +423,7 @@ namespace UniGLTF
public void ImportAsset()
{
if (!IsUnderAssetsFolder)
if (!IsUnderWritableFolder)
{
throw new NotImplementedException();
}
@@ -389,7 +458,7 @@ namespace UniGLTF
public UnityEngine.Object[] GetSubAssets()
{
if (!IsUnderAssetsFolder)
if (!IsUnderWritableFolder)
{
throw new NotImplementedException();
}
@@ -399,7 +468,7 @@ namespace UniGLTF
public void CreateAsset(UnityEngine.Object o)
{
if (!IsUnderAssetsFolder)
if (!IsUnderWritableFolder)
{
throw new NotImplementedException();
}
@@ -421,7 +490,7 @@ namespace UniGLTF
public void AddObjectToAsset(UnityEngine.Object o)
{
if (!IsUnderAssetsFolder)
if (!IsUnderWritableFolder)
{
throw new NotImplementedException();
}
@@ -431,7 +500,7 @@ namespace UniGLTF
public T LoadAsset<T>() where T : UnityEngine.Object
{
if (!IsUnderAssetsFolder)
if (!IsUnderWritableFolder)
{
throw new NotImplementedException();
}
@@ -441,7 +510,7 @@ namespace UniGLTF
public UnityPath GenerateUniqueAssetPath()
{
if (!IsUnderAssetsFolder)
if (!IsUnderWritableFolder)
{
throw new NotImplementedException();
}
@@ -450,4 +519,11 @@ namespace UniGLTF
}
#endif
}
public enum PathType
{
Assets,
Packages,
Unsuported,
}
}

View File

@@ -163,19 +163,41 @@ namespace UniGLTF
{
var root = UnityPath.FromUnityPath(".");
Assert.IsFalse(root.IsNull);
Assert.IsFalse(root.IsUnderAssetsFolder);
Assert.IsFalse(root.IsUnderWritableFolder);
Assert.AreEqual(UnityPath.FromUnityPath("."), root);
var assets = UnityPath.FromUnityPath("Assets");
Assert.IsFalse(assets.IsNull);
Assert.IsTrue(assets.IsUnderAssetsFolder);
Assert.IsFalse(assets.IsUnderWritableFolder);
var rootChild = root.Child("Assets");
Assert.AreEqual(assets, rootChild);
var rootChildAssets = root.Child("Assets");
Assert.AreEqual(assets, rootChildAssets);
var assetsChild = assets.Child("Hoge");
var hoge = UnityPath.FromUnityPath("Assets/Hoge");
Assert.AreEqual(assetsChild, hoge);
var assetsChildHoge = assets.Child("Hoge");
var assetsHoge = UnityPath.FromUnityPath("Assets/Hoge");
Assert.IsTrue(assetsChildHoge.IsUnderWritableFolder);
Assert.IsTrue(assetsHoge.IsUnderWritableFolder);
Assert.AreEqual(assetsChildHoge, assetsHoge);
var packages = UnityPath.FromUnityPath("Packages");
Assert.IsFalse(packages.IsNull);
Assert.IsFalse(packages.IsUnderWritableFolder);
var rootChildPackages = root.Child("Packages");
Assert.AreEqual(packages, rootChildPackages);
var packagesChildNUnit = packages.Child("com.unity.ext.nunit");
var packagesNUnit = UnityPath.FromUnityPath("Packages/com.unity.ext.nunit");
Assert.IsFalse(packages.IsUnderWritableFolder);
Assert.IsFalse(packagesNUnit.IsUnderWritableFolder);
Assert.AreEqual(packagesChildNUnit, packagesNUnit);
var packagesChildHoge = packages.Child("Hoge");
var packagesHoge = UnityPath.FromUnityPath("Packages/Hoge");
Assert.IsFalse(packagesChildHoge.IsUnderWritableFolder);
Assert.IsFalse(packagesHoge.IsUnderWritableFolder);
Assert.AreEqual(packagesChildHoge, packagesHoge);
//var children = root.TraverseDir().ToArray();
}

View File

@@ -41,7 +41,7 @@ namespace VRM
static void ImportVrm(UnityPath vrmPath)
{
if (!vrmPath.IsUnderAssetsFolder)
if (!vrmPath.IsUnderWritableFolder)
{
throw new Exception();
}
@@ -53,9 +53,9 @@ namespace VRM
public static void ImportVrmAndCreatePrefab(string vrmPath, UnityPath prefabPath)
{
if (!prefabPath.IsUnderAssetsFolder)
if (!prefabPath.IsUnderWritableFolder)
{
Debug.LogWarningFormat("out of asset path: {0}", prefabPath);
Debug.LogWarningFormat("out of Asset or writable Packages folder: {0}", prefabPath);
return;
}

View File

@@ -263,9 +263,9 @@ namespace VRM
// 新規で作成されるアセットはすべてこのフォルダの中に作る。上書きチェックはしない
var assetFolder = EditorUtility.SaveFolderPanel("select asset save folder", Path.GetDirectoryName(folder), "VrmIntegrated");
var unityPath = UniGLTF.UnityPath.FromFullpath(assetFolder);
if (!unityPath.IsUnderAssetsFolder)
if (!unityPath.IsUnderWritableFolder)
{
EditorUtility.DisplayDialog("asset folder", "Target folder must be in the `Assets` folder", "cancel");
EditorUtility.DisplayDialog("asset folder", "Target folder must be in the Assets or writable Packages folder", "cancel");
return;
}
assetFolder = unityPath.Value;

View File

@@ -288,7 +288,7 @@ namespace UniVRM10
Debug.Log("exportedBytes: " + exportedBytes.Length);
var assetPath = UniGLTF.UnityPath.FromFullpath(path);
if (assetPath.IsUnderAssetsFolder)
if (assetPath.IsUnderWritableFolder)
{
// asset folder 内。import を発動
assetPath.ImportAsset();

View File

@@ -20,9 +20,9 @@ namespace UniVRM10
return null;
}
var unityPath = UnityPath.FromFullpath(path);
if (!unityPath.IsUnderAssetsFolder)
if (!unityPath.IsUnderWritableFolder)
{
EditorUtility.DisplayDialog("error", "The specified path is not inside of Assets/", "OK");
EditorUtility.DisplayDialog("error", "The specified path is not inside of Assets or writable Packages", "OK");
return null;
}