// Magica Cloth. // Copyright (c) MagicaSoft, 2020-2022. // https://magicasoft.jp using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; namespace MagicaCloth { /// /// ClothParamクラスのプリセットに関するユーティリティ /// public static class EditorPresetUtility { const string configName = "preset folder"; public static void DrawPresetButton(MonoBehaviour owner, ClothParams clothParam) { using (var horizontalScope = new GUILayout.HorizontalScope()) { EditorGUILayout.LabelField("Parameters", EditorStyles.boldLabel); GUI.backgroundColor = Color.green; if (EditorGUILayout.DropdownButton(new GUIContent("Preset"), FocusType.Keyboard, GUILayout.Width(70), GUILayout.Height(16))) { CreatePresetPopupMenu(owner, clothParam); GUI.backgroundColor = Color.white; GUIUtility.ExitGUI(); } GUI.backgroundColor = Color.white; if (GUILayout.Button("Save", GUILayout.Width(40), GUILayout.Height(16))) { SavePreset(owner, clothParam); GUIUtility.ExitGUI(); } if (GUILayout.Button("Load", GUILayout.Width(40), GUILayout.Height(16))) { LoadPreset(owner, clothParam); GUIUtility.ExitGUI(); } } } private static string GetComponentTypeName(MonoBehaviour owner) { string componentTypeName = string.Empty; if (owner is MagicaBoneCloth) componentTypeName = "BoneCloth"; else if (owner is MagicaBoneSpring) componentTypeName = "BoneSpring"; else if (owner is MagicaMeshCloth) componentTypeName = "MeshCloth"; else if (owner is MagicaMeshSpring) componentTypeName = "MeshSpring"; return componentTypeName; } private class PresetInfo { public string presetPath; public string presetName; public TextAsset text; } private static void CreatePresetPopupMenu(MonoBehaviour owner, ClothParams clothParam) { // コンポーネントにより検索するプリセット名を変更する string presetTypeName = GetComponentTypeName(owner); if (string.IsNullOrEmpty(presetTypeName)) return; var guidArray = AssetDatabase.FindAssets($"{presetTypeName} t:" + nameof(TextAsset)); if (guidArray == null) return; Dictionary> dict = new Dictionary>(); foreach (var guid in guidArray) { var filePath = AssetDatabase.GUIDToAssetPath(guid); // json確認 if (filePath.EndsWith(".json") == false) continue; var text = AssetDatabase.LoadAssetAtPath(filePath); if (text) { var info = new PresetInfo(); info.presetPath = filePath; var fname = Path.GetFileNameWithoutExtension(filePath); fname = fname.Replace(presetTypeName, ""); if (fname.StartsWith("_")) fname = fname.Remove(0, 1); // 頭の_は削除する info.presetName = fname; info.text = text; // ディレクトリごとに記録する var dirName = Path.GetDirectoryName(filePath); if (dict.ContainsKey(dirName) == false) { dict.Add(dirName, new List()); } dict[dirName].Add(info); } } // ポップアップメニューの作成 // ディレクトリごとにセパレータで分けて表示する var menu = new GenericMenu(); int line = 0; foreach (var kv in dict) { if (line > 0) { menu.AddSeparator(""); } foreach (var info in kv.Value) { var textAsset = info.text; var presetName = info.presetName; var presetPath = info.presetPath; menu.AddItem(new GUIContent(presetName), false, () => { var json = textAsset.text; //Debug.Log(json); // load Debug.Log("Load preset file:" + presetPath); LoadClothParam(owner, clothParam, json); Debug.Log("Complete."); }); } line++; } menu.ShowAsContext(); } /// /// プリセットファイル保存 /// /// private static void SavePreset(MonoBehaviour owner, ClothParams clothParam) { // フォルダを読み込み string folder = EditorUserSettings.GetConfigValue(configName); // 接頭語 string presetTypeName = GetComponentTypeName(owner); // 保存ダイアログ string path = UnityEditor.EditorUtility.SaveFilePanelInProject( "Save Preset", $"{presetTypeName}_xxx", "json", "Enter a name for the preset json.", folder ); if (string.IsNullOrEmpty(path)) return; // フォルダを記録 folder = Path.GetDirectoryName(path); EditorUserSettings.SetConfigValue(configName, folder); Debug.Log("Save preset file:" + path); // json string json = JsonUtility.ToJson(clothParam); // save File.WriteAllText(path, json); AssetDatabase.Refresh(); Debug.Log("Complete."); } /// /// プリセットファイル読み込み /// /// /// private static void LoadPreset(MonoBehaviour owner, ClothParams clothParam) { // フォルダを読み込み string folder = EditorUserSettings.GetConfigValue(configName); // 読み込みダイアログ string path = UnityEditor.EditorUtility.OpenFilePanel("Load Preset", folder, "json"); if (string.IsNullOrEmpty(path)) return; // フォルダを記録 folder = Path.GetDirectoryName(path); EditorUserSettings.SetConfigValue(configName, folder); // json Debug.Log("Load preset file:" + path); string json = File.ReadAllText(path); // load LoadClothParam(owner, clothParam, json); Debug.Log("Complete."); } /// /// jsonテキストからパラメータを復元する /// /// /// /// private static void LoadClothParam(MonoBehaviour owner, ClothParams clothParam, string json) { if (string.IsNullOrEmpty(json) == false) { // 上書きしないプロパティを保持 Transform influenceTarget = clothParam.GetInfluenceTarget(); Transform disableReferenceObject = clothParam.DisableReferenceObject; //Transform directionalDampingObject = clothParam.DirectionalDampingObject; // undo Undo.RecordObject(owner, "Load preset"); JsonUtility.FromJsonOverwrite(json, clothParam); // 上書きしないプロパティを書き戻し clothParam.SetInfluenceTarget(influenceTarget); clothParam.DisableReferenceObject = disableReferenceObject; //clothParam.DirectionalDampingObject = directionalDampingObject; } } } }