using UniGLTF; using UnityEngine; using System.Linq; using System.IO; using UnityEditor; #if UNITY_2020_2_OR_NEWER using UnityEditor.AssetImporters; #else using UnityEditor.Experimental.AssetImporters; #endif namespace UniVRM10 { public static class EditorVrm { static ExpressionKey CreateKey(UniGLTF.Extensions.VRMC_vrm.Expression expression) { if (expression.Preset == UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.custom) { return ExpressionKey.CreateCustom(expression.Name); } else { return ExpressionKey.CreateFromPreset(expression.Preset); } } public static void OnGUI(ScriptedImporter importer, GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm) { var hasExternal = importer.GetExternalObjectMap().Any(x => x.Value is VRM10MetaObject || x.Value is VRM10ExpressionAvatar || x.Value is VRM10Expression); using (new TmpGuiEnable(!hasExternal)) { if (GUILayout.Button("Extract Meta And Expressions ...")) { Extract(importer, parser); } } // meta importer.DrawRemapGUI(new SubAssetKey[] { VRM10MetaObject.SubAssetKey }); // expression avatar importer.DrawRemapGUI(new SubAssetKey[] { VRM10ExpressionAvatar.SubAssetKey }); // expressions importer.DrawRemapGUI(vrm.Expressions.Select(x => CreateKey(x).SubAssetKey)); if (GUILayout.Button("Clear")) { importer.ClearExternalObjects(); importer.ClearExternalObjects(); importer.ClearExternalObjects(); } } /// /// $"{assetPath without extension}.{folderName}" /// /// /// /// static string GetAndCreateFolder(string assetPath, string suffix) { var path = $"{Path.GetDirectoryName(assetPath)}/{Path.GetFileNameWithoutExtension(assetPath)}{suffix}"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } return path; } /// /// SubAssetを外部ファイルに展開する /// public static void Extract(ScriptedImporter importer, GltfParser parser) { if (string.IsNullOrEmpty(importer.assetPath)) { return; } // meta { var path = GetAndCreateFolder(importer.assetPath, ".Meta"); foreach (var (key, asset) in importer.GetSubAssets(importer.assetPath)) { asset.ExtractSubAsset($"{path}/{asset.name}.asset", false); } } { // expressions var path = GetAndCreateFolder(importer.assetPath, ".Expressions"); foreach (var (key, asset) in importer.GetSubAssets(importer.assetPath)) { asset.ExtractSubAsset($"{path}/{asset.name}.asset", false); } } { // expressions var path = GetAndCreateFolder(importer.assetPath, ".ExpressionAvatar"); foreach (var (key, asset) in importer.GetSubAssets(importer.assetPath)) { asset.ExtractSubAsset($"{path}/{asset.name}.asset", false); } // external な expressionAvatar.Clips に 再代入する var expressionAvatar = importer.GetExternalObjectMap().Select(x => x.Value as VRM10ExpressionAvatar).FirstOrDefault(x => x != null); var expressions = importer.GetExternalObjectMap().Select(x => x.Value as VRM10Expression).Where(x => x != null).ToList(); expressionAvatar.Clips = expressions; var avatarPath = AssetDatabase.GetAssetPath(expressionAvatar); if (!string.IsNullOrEmpty(avatarPath)) { EditorUtility.SetDirty(expressionAvatar); AssetDatabase.WriteImportSettingsIfDirty(avatarPath); } } AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate); } } }