From 2e6ded5a7faae38aae986d22ccc0a9e3a08975ce Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 26 Feb 2021 19:00:48 +0900 Subject: [PATCH] =?UTF-8?q?ImporterContext=E3=81=AEAssetImport=E5=90=91?= =?UTF-8?q?=E3=81=91=E3=81=AE=E6=A9=9F=E8=83=BD=E3=82=92=E3=80=81EditorImp?= =?UTF-8?q?orterContext=E3=81=AB=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EditorImporterContext #758 --- .../UniGLTF/Editor/EditorImporterContext.cs | 245 ++++++++++++++++++ .../Editor/EditorImporterContext.cs.meta | 11 + .../Runtime/UniGLTF/IO/ImporterContext.cs | 237 +---------------- Assets/UniGLTF/Tests/UniGLTF.Tests.asmdef | 3 +- Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs | 3 +- .../Editor/Format/VRMEditorImporterContext.cs | 91 +++++++ .../Format/VRMEditorImporterContext.cs.meta | 11 + Assets/VRM/Editor/Format/VRMImporterMenu.cs | 7 +- .../Editor/Format/vrmAssetPostprocessor.cs | 8 +- Assets/VRM/Editor/Meta/VRMMetaEditor.cs | 2 +- Assets/VRM/Runtime/IO/VRMImporterContext.cs | 79 +----- 11 files changed, 383 insertions(+), 314 deletions(-) create mode 100644 Assets/UniGLTF/Editor/EditorImporterContext.cs create mode 100644 Assets/UniGLTF/Editor/EditorImporterContext.cs.meta create mode 100644 Assets/VRM/Editor/Format/VRMEditorImporterContext.cs create mode 100644 Assets/VRM/Editor/Format/VRMEditorImporterContext.cs.meta diff --git a/Assets/UniGLTF/Editor/EditorImporterContext.cs b/Assets/UniGLTF/Editor/EditorImporterContext.cs new file mode 100644 index 000000000..a7af84aed --- /dev/null +++ b/Assets/UniGLTF/Editor/EditorImporterContext.cs @@ -0,0 +1,245 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEditor; +using UnityEngine; + + +namespace UniGLTF +{ + /// + /// Editor で Asset 化する場合専用 + /// + /// GameObject を prefab 化するので、prefab の元になった GameObject は破棄対象となる。 + /// + /// + public class EditorImporterContext : IDisposable + { + ImporterContext m_context; + + public EditorImporterContext(ImporterContext context) + { + m_context = context; + } + + public void Dispose() + { + m_context.Dispose(); + + if (m_context.Root != null) + { + // Destroy the GameObject that became the basis of Prefab + GameObject.DestroyImmediate(m_context.Root); + } + } + + public virtual IEnumerable ObjectsForSubAsset() + { + foreach (var x in m_context.TextureFactory.ObjectsForSubAsset()) + { + yield return x; + } + foreach (var x in m_context.MaterialFactory.ObjectsForSubAsset()) + { + yield return x; + } + foreach (var x in m_context.Meshes) { yield return x.Mesh; } + foreach (var x in m_context.AnimationClips) { yield return x; } + } + + /// + /// Destroy assets that created ImporterContext. This function is clean up for importer error. + /// + public virtual void EditorDestroyRootAndAssets() + { + // Remove hierarchy + if (m_context.Root != null) GameObject.DestroyImmediate(m_context.Root); + + // Remove resources. materials, textures meshes etc... + foreach (var o in ObjectsForSubAsset()) + { + UnityEngine.Object.DestroyImmediate(o, true); + } + } + + public virtual UnityPath GetAssetPath(UnityPath prefabPath, UnityEngine.Object o, bool meshAsSubAsset) + { + if (o is Material) + { + var materialDir = prefabPath.GetAssetFolder(".Materials"); + var materialPath = materialDir.Child(o.name.EscapeFilePath() + ".asset"); + return materialPath; + } + else if (o is Texture2D) + { + var textureDir = prefabPath.GetAssetFolder(".Textures"); + var texturePath = textureDir.Child(o.name.EscapeFilePath() + ".asset"); + return texturePath; + } + else if (o is Mesh && !meshAsSubAsset) + { + var meshDir = prefabPath.GetAssetFolder(".Meshes"); + var meshPath = meshDir.Child(o.name.EscapeFilePath() + ".asset"); + return meshPath; + } + else + { + return default(UnityPath); + } + } + + public virtual bool AvoidOverwriteAndLoad(UnityPath assetPath, UnityEngine.Object o) + { + if (o is Material) + { + var loaded = assetPath.LoadAsset(); + + // replace component reference + foreach (var mesh in m_context.Meshes) + { + foreach (var r in mesh.Renderers) + { + for (int i = 0; i < r.sharedMaterials.Length; ++i) + { + if (r.sharedMaterials.Contains(o)) + { + r.sharedMaterials = r.sharedMaterials.Select(x => x == o ? loaded : x).ToArray(); + } + } + } + } + + return true; + } + + return false; + } + + public void SaveAsAsset(UnityPath prefabPath, bool meshAsSubAsset = false) + { + m_context.ShowMeshes(); + + //var prefabPath = PrefabPath; + if (prefabPath.IsFileExists) + { + // clear SubAssets + foreach (var x in prefabPath.GetSubAssets().Where(x => !(x is GameObject) && !(x is Component))) + { + GameObject.DestroyImmediate(x, true); + } + } + + // + // save sub assets + // + var paths = new List(){ + prefabPath + }; + foreach (var o in ObjectsForSubAsset()) + { + if (o == null) continue; + + var assetPath = GetAssetPath(prefabPath, o, meshAsSubAsset); + if (!assetPath.IsNull) + { + if (assetPath.IsFileExists) + { + if (AvoidOverwriteAndLoad(assetPath, o)) + { + // 上書きせずに既存のアセットからロードして置き換えた + continue; + } + } + + // アセットとして書き込む + assetPath.Parent.EnsureFolder(); + assetPath.CreateAsset(o); + paths.Add(assetPath); + } + else + { + // save as subasset + prefabPath.AddObjectToAsset(o); + } + } + + // Create or update Main Asset + if (prefabPath.IsFileExists) + { + Debug.LogFormat("replace prefab: {0}", prefabPath); + var prefab = prefabPath.LoadAsset(); +#if UNITY_2018_3_OR_NEWER + PrefabUtility.SaveAsPrefabAssetAndConnect(m_context.Root, prefabPath.Value, InteractionMode.AutomatedAction); +#else + PrefabUtility.ReplacePrefab(Root, prefab, ReplacePrefabOptions.ReplaceNameBased); +#endif + + } + else + { + Debug.LogFormat("create prefab: {0}", prefabPath); +#if UNITY_2018_3_OR_NEWER + PrefabUtility.SaveAsPrefabAssetAndConnect(m_context.Root, prefabPath.Value, InteractionMode.AutomatedAction); +#else + PrefabUtility.CreatePrefab(prefabPath.Value, Root); +#endif + } + foreach (var x in paths) + { + x.ImportAsset(); + } + } + + /// + /// Extract images from glb or gltf out of Assets folder. + /// + /// + public void ExtractImages(UnityPath prefabPath) + { + var prefabParentDir = prefabPath.Parent; + + // glb buffer + var folder = prefabPath.GetAssetFolder(".Textures"); + + // + // https://answers.unity.com/questions/647615/how-to-update-import-settings-for-newly-created-as.html + // + int created = 0; + for (int i = 0; i < m_context.GLTF.textures.Count; ++i) + { + folder.EnsureFolder(); + + var gltfTexture = m_context.GLTF.textures[i]; + var gltfImage = m_context.GLTF.images[gltfTexture.source]; + var src = m_context.Storage.GetPath(gltfImage.uri); + if (UnityPath.FromFullpath(src).IsUnderAssetsFolder) + { + // asset is exists. + } + else + { + var byteSegment = m_context.GLTF.GetImageBytes(m_context.Storage, gltfTexture.source); + var textureName = gltfTexture.name; + + // path + var dst = folder.Child(textureName + gltfImage.GetExt()); + File.WriteAllBytes(dst.FullPath, byteSegment.ToArray()); + dst.ImportAsset(); + + // make relative path from PrefabParentDir + gltfImage.uri = dst.Value.Substring(prefabParentDir.Value.Length + 1); + ++created; + } + } + + if (created > 0) + { + AssetDatabase.Refresh(); + } + + // texture will load from assets + m_context.TextureFactory.ImageBaseDir = prefabParentDir; + } + } +} diff --git a/Assets/UniGLTF/Editor/EditorImporterContext.cs.meta b/Assets/UniGLTF/Editor/EditorImporterContext.cs.meta new file mode 100644 index 000000000..bb14f8f6b --- /dev/null +++ b/Assets/UniGLTF/Editor/EditorImporterContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1c496f43ae12f9041a16af0489727587 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index f7829e033..7e455a320 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -2,11 +2,7 @@ using System.Linq; using System.Collections.Generic; using UnityEngine; -using System.IO; using UniGLTF.AltTask; -#if UNITY_EDITOR -using UnityEditor; -#endif namespace UniGLTF { @@ -230,237 +226,22 @@ namespace UniGLTF public List AnimationClips = new List(); #endregion - protected virtual IEnumerable ObjectsForSubAsset() - { - foreach (var x in TextureFactory.ObjectsForSubAsset()) - { - yield return x; - } - foreach (var x in MaterialFactory.ObjectsForSubAsset()) - { - yield return x; - } - foreach (var x in Meshes) { yield return x.Mesh; } - foreach (var x in AnimationClips) { yield return x; } - } - -#if UNITY_EDITOR - #region Assets - public bool MeshAsSubAsset = false; - - protected virtual UnityPath GetAssetPath(UnityPath prefabPath, UnityEngine.Object o) - { - if (o is Material) - { - var materialDir = prefabPath.GetAssetFolder(".Materials"); - var materialPath = materialDir.Child(o.name.EscapeFilePath() + ".asset"); - return materialPath; - } - else if (o is Texture2D) - { - var textureDir = prefabPath.GetAssetFolder(".Textures"); - var texturePath = textureDir.Child(o.name.EscapeFilePath() + ".asset"); - return texturePath; - } - else if (o is Mesh && !MeshAsSubAsset) - { - var meshDir = prefabPath.GetAssetFolder(".Meshes"); - var meshPath = meshDir.Child(o.name.EscapeFilePath() + ".asset"); - return meshPath; - } - else - { - return default(UnityPath); - } - } - - public virtual bool AvoidOverwriteAndLoad(UnityPath assetPath, UnityEngine.Object o) - { - if (o is Material) - { - var loaded = assetPath.LoadAsset(); - - // replace component reference - foreach (var mesh in Meshes) - { - foreach (var r in mesh.Renderers) - { - for (int i = 0; i < r.sharedMaterials.Length; ++i) - { - if (r.sharedMaterials.Contains(o)) - { - r.sharedMaterials = r.sharedMaterials.Select(x => x == o ? loaded : x).ToArray(); - } - } - } - } - - return true; - } - - return false; - } - - public void SaveAsAsset(UnityPath prefabPath) - { - ShowMeshes(); - - //var prefabPath = PrefabPath; - if (prefabPath.IsFileExists) - { - // clear SubAssets - foreach (var x in prefabPath.GetSubAssets().Where(x => !(x is GameObject) && !(x is Component))) - { - GameObject.DestroyImmediate(x, true); - } - } - - // - // save sub assets - // - var paths = new List(){ - prefabPath - }; - foreach (var o in ObjectsForSubAsset()) - { - if (o == null) continue; - - var assetPath = GetAssetPath(prefabPath, o); - if (!assetPath.IsNull) - { - if (assetPath.IsFileExists) - { - if (AvoidOverwriteAndLoad(assetPath, o)) - { - // 上書きせずに既存のアセットからロードして置き換えた - continue; - } - } - - // アセットとして書き込む - assetPath.Parent.EnsureFolder(); - assetPath.CreateAsset(o); - paths.Add(assetPath); - } - else - { - // save as subasset - prefabPath.AddObjectToAsset(o); - } - } - - // Create or update Main Asset - if (prefabPath.IsFileExists) - { - Debug.LogFormat("replace prefab: {0}", prefabPath); - var prefab = prefabPath.LoadAsset(); -#if UNITY_2018_3_OR_NEWER - PrefabUtility.SaveAsPrefabAssetAndConnect(Root, prefabPath.Value, InteractionMode.AutomatedAction); -#else - PrefabUtility.ReplacePrefab(Root, prefab, ReplacePrefabOptions.ReplaceNameBased); -#endif - - } - else - { - Debug.LogFormat("create prefab: {0}", prefabPath); -#if UNITY_2018_3_OR_NEWER - PrefabUtility.SaveAsPrefabAssetAndConnect(Root, prefabPath.Value, InteractionMode.AutomatedAction); -#else - PrefabUtility.CreatePrefab(prefabPath.Value, Root); -#endif - } - foreach (var x in paths) - { - x.ImportAsset(); - } - } - - /// - /// Extract images from glb or gltf out of Assets folder. - /// - /// - public void ExtractImages(UnityPath prefabPath) - { - var prefabParentDir = prefabPath.Parent; - - // glb buffer - var folder = prefabPath.GetAssetFolder(".Textures"); - - // - // https://answers.unity.com/questions/647615/how-to-update-import-settings-for-newly-created-as.html - // - int created = 0; - for (int i = 0; i < GLTF.textures.Count; ++i) - { - folder.EnsureFolder(); - - var gltfTexture = GLTF.textures[i]; - var gltfImage = GLTF.images[gltfTexture.source]; - var src = Storage.GetPath(gltfImage.uri); - if (UnityPath.FromFullpath(src).IsUnderAssetsFolder) - { - // asset is exists. - } - else - { - var byteSegment = GLTF.GetImageBytes(Storage, gltfTexture.source); - var textureName = gltfTexture.name; - - // path - var dst = folder.Child(textureName + gltfImage.GetExt()); - File.WriteAllBytes(dst.FullPath, byteSegment.ToArray()); - dst.ImportAsset(); - - // make relative path from PrefabParentDir - gltfImage.uri = dst.Value.Substring(prefabParentDir.Value.Length + 1); - ++created; - } - } - - if (created > 0) - { - AssetDatabase.Refresh(); - } - - // texture will load from assets - m_textureFactory.ImageBaseDir = prefabParentDir; - } - #endregion -#endif - - /// - /// Destroy the GameObject that became the basis of Prefab - /// - public void EditorDestroyRoot() - { - if (Root != null) GameObject.DestroyImmediate(Root); - } - - /// - /// Destroy assets that created ImporterContext. This function is clean up for importer error. - /// - public void EditorDestroyRootAndAssets() - { - // Remove hierarchy - if (Root != null) GameObject.DestroyImmediate(Root); - - // Remove resources. materials, textures meshes etc... - foreach (var o in ObjectsForSubAsset()) - { - UnityEngine.Object.DestroyImmediate(o, true); - } - } - /// /// Importに使った一時オブジェクトを破棄する /// /// 変換のあるテクスチャで、変換前のもの /// normal, occlusion, metallicRoughness /// - public void Dispose() + public virtual void Dispose() { - // m_textureFactory.Dispose(); + foreach (var x in m_textureFactory.Textures) + { + if (!x.IsUsed) + { + // Destroy temporary texture object + UnityEngine.Object.Destroy(x.Texture); + } + } } /// diff --git a/Assets/UniGLTF/Tests/UniGLTF.Tests.asmdef b/Assets/UniGLTF/Tests/UniGLTF.Tests.asmdef index 326fd1ce3..2feff781c 100644 --- a/Assets/UniGLTF/Tests/UniGLTF.Tests.asmdef +++ b/Assets/UniGLTF/Tests/UniGLTF.Tests.asmdef @@ -1,7 +1,8 @@ { "name": "UniGLTF.Tests", "references": [ - "UniGLTF" + "UniGLTF", + "UniGLTF.Editor" ], "optionalUnityReferences": [ "TestAssemblies" diff --git a/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs b/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs index cc2ce351d..620577672 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs @@ -133,7 +133,8 @@ namespace UniGLTF GameObject.DestroyImmediate(go); if (context != null) { - context.EditorDestroyRootAndAssets(); + var editor = new EditorImporterContext(context); + editor.EditorDestroyRootAndAssets(); } } } diff --git a/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs b/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs new file mode 100644 index 000000000..3d37da6cf --- /dev/null +++ b/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs @@ -0,0 +1,91 @@ +using System.Collections; +using System.Collections.Generic; +using UniGLTF; +using UnityEngine; + +namespace VRM +{ + public class VRMEditorImporterContext : EditorImporterContext + { + VRMImporterContext m_context; + + public VRMEditorImporterContext(VRMImporterContext context) : base(context) + { + m_context = context; + } + + public override IEnumerable ObjectsForSubAsset() + { + foreach (var x in base.ObjectsForSubAsset()) + { + yield return x; + } + + yield return m_context.AvatarDescription; + yield return m_context.HumanoidAvatar; + + if (m_context.BlendShapeAvatar != null && m_context.BlendShapeAvatar.Clips != null) + { + foreach (var x in m_context.BlendShapeAvatar.Clips) + { + yield return x; + } + } + yield return m_context.BlendShapeAvatar; + + yield return m_context.Meta; + } + + public override bool AvoidOverwriteAndLoad(UnityPath assetPath, UnityEngine.Object o) + { + if (o is BlendShapeAvatar) + { + var loaded = assetPath.LoadAsset(); + var proxy = m_context.Root.GetComponent(); + proxy.BlendShapeAvatar = loaded; + + return true; + } + + if (o is BlendShapeClip) + { + return true; + } + + return base.AvoidOverwriteAndLoad(assetPath, o); + } + + public override UnityPath GetAssetPath(UnityPath prefabPath, UnityEngine.Object o, bool meshAsSubAsset) + { + if (o is BlendShapeAvatar + || o is BlendShapeClip) + { + var dir = prefabPath.GetAssetFolder(".BlendShapes"); + var assetPath = dir.Child(o.name.EscapeFilePath() + ".asset"); + return assetPath; + } + else if (o is Avatar) + { + var dir = prefabPath.GetAssetFolder(".Avatar"); + var assetPath = dir.Child(o.name.EscapeFilePath() + ".asset"); + return assetPath; + } + else if (o is VRMMetaObject) + { + var dir = prefabPath.GetAssetFolder(".MetaObject"); + var assetPath = dir.Child(o.name.EscapeFilePath() + ".asset"); + return assetPath; + } + else if (o is UniHumanoid.AvatarDescription) + { + var dir = prefabPath.GetAssetFolder(".AvatarDescription"); + var assetPath = dir.Child(o.name.EscapeFilePath() + ".asset"); + return assetPath; + } + else + { + return base.GetAssetPath(prefabPath, o, meshAsSubAsset); + } + } + } +} diff --git a/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs.meta b/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs.meta new file mode 100644 index 000000000..90ec1207c --- /dev/null +++ b/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 58b502cc8f926b74fadb536f3b033100 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM/Editor/Format/VRMImporterMenu.cs b/Assets/VRM/Editor/Format/VRMImporterMenu.cs index 0741f360b..ca5e8f7ed 100644 --- a/Assets/VRM/Editor/Format/VRMImporterMenu.cs +++ b/Assets/VRM/Editor/Format/VRMImporterMenu.cs @@ -53,7 +53,8 @@ namespace VRM var parser = new GltfParser(); parser.ParseGlb(File.ReadAllBytes(path)); var context = new VRMImporterContext(parser); - context.ExtractImages(prefabPath); + var editor = new VRMEditorImporterContext(context); + editor.ExtractImages(prefabPath); EditorApplication.delayCall += () => { @@ -61,8 +62,8 @@ namespace VRM // after textures imported // context.Load(); - context.SaveAsAsset(prefabPath); - context.EditorDestroyRoot(); + editor.SaveAsAsset(prefabPath); + editor.Dispose(); }; } } diff --git a/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs b/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs index 5806cdfad..a56705d04 100644 --- a/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs +++ b/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using UniGLTF; using UnityEditor; using UnityEngine; @@ -53,7 +52,8 @@ namespace VRM // save texture assets ! var context = new VRMImporterContext(parser); - context.ExtractImages(prefabPath); + var editor = new VRMEditorImporterContext(context); + editor.ExtractImages(prefabPath); EditorApplication.delayCall += () => { @@ -61,8 +61,8 @@ namespace VRM // after textures imported // context.Load(); - context.SaveAsAsset(prefabPath); - context.EditorDestroyRoot(); + editor.SaveAsAsset(prefabPath); + editor.Dispose(); }; } } diff --git a/Assets/VRM/Editor/Meta/VRMMetaEditor.cs b/Assets/VRM/Editor/Meta/VRMMetaEditor.cs index fac50451f..e0b1295d9 100644 --- a/Assets/VRM/Editor/Meta/VRMMetaEditor.cs +++ b/Assets/VRM/Editor/Meta/VRMMetaEditor.cs @@ -16,7 +16,7 @@ namespace VRM private void OnEnable() { - m_VRMMetaObjectProp = serializedObject.FindProperty("Meta"); + m_VRMMetaObjectProp = serializedObject.FindProperty(nameof(VRMMeta.Meta)); m_Inspector = Editor.CreateEditor(m_VRMMetaObjectProp.objectReferenceValue); } diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index 79709b567..195f6044b 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -298,81 +298,8 @@ namespace VRM return meta; } - - protected override IEnumerable ObjectsForSubAsset() - { - foreach (var x in base.ObjectsForSubAsset()) - { - yield return x; - } - - yield return AvatarDescription; - yield return HumanoidAvatar; - - if (BlendShapeAvatar != null && BlendShapeAvatar.Clips != null) - { - foreach (var x in BlendShapeAvatar.Clips) - { - yield return x; - } - } - yield return BlendShapeAvatar; - - yield return Meta; - } - -#if UNITY_EDITOR - public override bool AvoidOverwriteAndLoad(UnityPath assetPath, UnityEngine.Object o) - { - if (o is BlendShapeAvatar) - { - var loaded = assetPath.LoadAsset(); - var proxy = Root.GetComponent(); - proxy.BlendShapeAvatar = loaded; - - return true; - } - - if (o is BlendShapeClip) - { - return true; - } - - return base.AvoidOverwriteAndLoad(assetPath, o); - } - - protected override UnityPath GetAssetPath(UnityPath prefabPath, UnityEngine.Object o) - { - if (o is BlendShapeAvatar - || o is BlendShapeClip) - { - var dir = prefabPath.GetAssetFolder(".BlendShapes"); - var assetPath = dir.Child(o.name.EscapeFilePath() + ".asset"); - return assetPath; - } - else if (o is Avatar) - { - var dir = prefabPath.GetAssetFolder(".Avatar"); - var assetPath = dir.Child(o.name.EscapeFilePath() + ".asset"); - return assetPath; - } - else if (o is VRMMetaObject) - { - var dir = prefabPath.GetAssetFolder(".MetaObject"); - var assetPath = dir.Child(o.name.EscapeFilePath() + ".asset"); - return assetPath; - } - else if (o is UniHumanoid.AvatarDescription) - { - var dir = prefabPath.GetAssetFolder(".AvatarDescription"); - var assetPath = dir.Child(o.name.EscapeFilePath() + ".asset"); - return assetPath; - } - else - { - return base.GetAssetPath(prefabPath, o); - } - } -#endif } + + + }