VRMShaders.PathObject を追加。 MigrationMenu で使う。

This commit is contained in:
ousttrue
2022-06-02 17:56:36 +09:00
parent 6c4561bdf6
commit 7030a4ddf4
5 changed files with 206 additions and 25 deletions

View File

@@ -343,8 +343,8 @@ namespace UniGLTF
}
public static UnityPath FromAsset(UnityEngine.Object asset)
{
var assetPath = AssetDatabase.GetAssetPath(asset);
{
var assetPath = AssetDatabase.GetAssetPath(asset);
if (string.IsNullOrEmpty(assetPath))
{
throw new System.ArgumentNullException();

View File

@@ -6,14 +6,18 @@ namespace UniVRM10
{
public static class MigrationMenu
{
static string s_lastPath = Application.dataPath;
static VRMShaders.PathObject s_lastPath = VRMShaders.PathObject.UnityAssets;
const string CONTEXT_MENU = "Assets/Migration: Vrm1";
[MenuItem(CONTEXT_MENU, true)]
static bool Enable()
{
var path = UniGLTF.UnityPath.FromAsset(Selection.activeObject);
if (Selection.activeObject == null)
{
return false;
}
var path = VRMShaders.PathObject.FromAsset(Selection.activeObject);
var isVrm = path.Extension.ToLower() == ".vrm";
return isVrm;
}
@@ -21,27 +25,30 @@ namespace UniVRM10
[MenuItem(CONTEXT_MENU, false)]
static void Exec()
{
var path = UniGLTF.UnityPath.FromAsset(Selection.activeObject);
var isVrm = path.Extension.ToLower() == ".vrm";
var path = VRMShaders.PathObject.FromAsset(Selection.activeObject);
var vrm1Bytes = MigrationVrm.Migrate(File.ReadAllBytes(path.FullPath));
// migrate
var vrm1Bytes = MigrationVrm.Migrate(path.ReadAllBytes());
var dst = EditorUtility.SaveFilePanel(
"Save vrm1 file",
s_lastPath,
$"{path.FileNameWithoutExtension}_vrm1",
"vrm");
if (string.IsNullOrEmpty(dst))
if (!s_lastPath.TrySaveDialog("Save vrm1 file", $"{path.Stem}_vrm1", out VRMShaders.PathObject dst))
{
return;
}
s_lastPath = Path.GetDirectoryName(dst);
s_lastPath = dst.Parent;
// write result
File.WriteAllBytes(dst, vrm1Bytes);
dst.WriteAllBytes(vrm1Bytes);
// immediately import for GUI update
UniGLTF.UnityPath.FromFullpath(dst).ImportAsset();
if (dst.IsUnderAsset)
{
// immediately import for GUI update
Debug.Log($"import: {dst}");
dst.ImportAsset();
}
else
{
Debug.Log($"write: {dst}");
}
}
}
}

View File

@@ -0,0 +1,171 @@
using System;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace VRMShaders
{
/// <summary>
/// UniGLTF.UnityPath (Assets の ひとつ上がルート) をすべてのパスが扱えるように拡張するのが趣旨。
/// readonly struct で Immutable であるという主張。
/// </summary>
public readonly struct PathObject
{
/// <summary>
/// * Delemeter は / を保証
/// * .. を解決済み
/// * フルパス
/// </summary>
readonly string _FullPath;
public string FullPath => _FullPath;
public string Extension => Path.GetExtension(_FullPath);
public string Stem => Path.GetFileNameWithoutExtension(_FullPath);
public PathObject Parent => FromFullPath(Path.GetDirectoryName(_FullPath));
public bool IsUnderAsset
{
get
{
var assets = UnityAssets;
return _FullPath.StartsWith(assets.FullPath);
}
}
/// <summary>
/// relative from UnityEngine.Application.dataPath
/// </summary>
/// <returns></returns>
public string UnityPath
{
get
{
var root = UnityRoot;
if (!_FullPath.StartsWith(root.FullPath))
{
throw new ArgumentException($"{_FullPath} is not under UnityPath");
}
return _FullPath.Substring(root.FullPath.Length);
}
}
static PathObject? _root;
public static PathObject UnityRoot
{
get
{
if (!_root.HasValue)
{
_root = FromFullPath(Path.GetDirectoryName(Application.dataPath) + "/");
}
return _root.Value;
}
}
public static PathObject UnityAssets => UnityRoot.Child("Assets/");
PathObject(string src)
{
if (string.IsNullOrEmpty(src))
{
throw new ArgumentNullException();
}
src = src.Replace('\\', '/');
if (src[0] == '/')
{
_FullPath = src;
}
else
{
if (src.Length >= 3 && src[1] == ':' && src[2] == '/')
{
_FullPath = src;
}
else
{
throw new ArgumentException($"{src} is not fullpath");
}
}
}
public override string ToString()
{
try
{
var unityPath = UnityPath;
return $"<unity:{unityPath}>";
}
catch (ArgumentException)
{
return $"<file:{_FullPath}>";
}
}
/// <param name="src">start with "X:/" on Windows else "/"</param>
/// <returns></returns>
public static PathObject FromFullPath(string src)
{
return new PathObject(src);
}
/// <param name="src">relative from UnityEngine.Application.dataPath</param>
/// <returns></returns>
public static PathObject FromUnityPath(string src)
{
return UnityRoot.Child(src);
}
public static PathObject FromAsset(UnityEngine.Object src)
{
if (src == null)
{
throw new ArgumentNullException();
}
var assetPath = AssetDatabase.GetAssetPath(src);
if (string.IsNullOrEmpty(assetPath))
{
throw new ArgumentException($"{src} is not asset");
}
return FromUnityPath(assetPath);
}
public PathObject Child(string child)
{
return FromFullPath(Path.Combine(_FullPath, child));
}
public byte[] ReadAllBytes()
{
return File.ReadAllBytes(_FullPath);
}
public void WriteAllBytes(byte[] data)
{
File.WriteAllBytes(_FullPath, data);
}
public void ImportAsset()
{
AssetDatabase.ImportAsset(UnityPath);
}
public bool TrySaveDialog(string title, string name, out PathObject dst)
{
var path = EditorUtility.SaveFilePanel(
title,
_FullPath,
name,
"vrm");
if (string.IsNullOrEmpty(path))
{
dst = default;
return false;
}
dst = PathObject.FromFullPath(path);
return true;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d16607c9cf9d05e46b5beec82002d4ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: eb31f565eeca6164694b06ccfe3bc251
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: