* Editor
エディタ用のフォルダを追加
* Config
MFU全体で必要そうなコンフィグ管理をします
* ConfigWindow
Configの設定用のウィンドウを用意します
Plugins/MMDLoader/Config にメニューが追加されます
* InspectorBase
typeof(Object)に引っ掛けるInspectorです
拡張子に応じてPMDInspector/VMDInspectorに振り分けます
ソース先頭のマクロをコメントアウトすることで、無効化できます
* PMDInspector
PMDLoaderWindow相当のものをInspectorで提供します
* VMDInspector
VMDLoaderWindow相当のものをInspectorで提供します
@@ -0,0 +1,53 @@ | ||
1 | +using UnityEngine; | |
2 | +using UnityEditor; | |
3 | + | |
4 | +namespace MMD | |
5 | +{ | |
6 | + public class ConfigWindow : EditorWindow | |
7 | + { | |
8 | + private static Config config; | |
9 | + private static string path; | |
10 | + | |
11 | + [MenuItem("Plugins/MMD Loader/Config")] | |
12 | + public static void Init() | |
13 | + { | |
14 | + GetWindow<ConfigWindow>("MFU Config"); | |
15 | + } | |
16 | + | |
17 | + // Windowが有効化されたとき | |
18 | + // フォーカスが外れて戻ってきたときや再度開かれたときなど | |
19 | + void OnEnable() | |
20 | + { | |
21 | + // オブジェクトを「Hierarchy」に表示しない。また、アセットの中にあれば、プロジェクトビューに表示しない | |
22 | + // オブジェクトがシーンに保存されない。また、新しいシーンを読んでも、オブジェクトが破棄されない | |
23 | + hideFlags = HideFlags.HideAndDontSave; | |
24 | + | |
25 | + if (config == null) | |
26 | + { | |
27 | + // 読み込む | |
28 | + config = MMD.Config.LoadAndCreate(); | |
29 | + | |
30 | + // なかったら作成する | |
31 | + if (config == null) | |
32 | + { | |
33 | + path = MMD.Config.GetConfigPath(); | |
34 | + config = CreateInstance<Config>(); | |
35 | + AssetDatabase.CreateAsset(config, path); | |
36 | + EditorUtility.SetDirty(config); | |
37 | + } | |
38 | + } | |
39 | + } | |
40 | + | |
41 | + // ウィンドウの描画処理 | |
42 | + void OnGUI() | |
43 | + { | |
44 | + // たいとる | |
45 | + EditorGUILayout.LabelField("MMD for Unity Configuration"); | |
46 | + EditorGUILayout.Space(); | |
47 | + | |
48 | + // あとは任せる | |
49 | + config.OnGUI(); | |
50 | + | |
51 | + } | |
52 | + } | |
53 | +} | |
\ No newline at end of file |
@@ -0,0 +1,91 @@ | ||
1 | +using UnityEngine; | |
2 | +using UnityEditor; | |
3 | +using System.Collections; | |
4 | +using MMD.PMD; | |
5 | +using System.IO; | |
6 | + | |
7 | +namespace MMD | |
8 | +{ | |
9 | + public class VMDInspector : Editor | |
10 | + { | |
11 | + // VMD Load option | |
12 | + public bool createAnimationFile; | |
13 | + public int interpolationQuality; | |
14 | + public GameObject pmdPrefab; | |
15 | + | |
16 | + // last selected item | |
17 | + private static string vmd_path = ""; | |
18 | + private static MMD.VMD.VMDFormat.Header vmd_header; | |
19 | + private static string message = ""; | |
20 | + | |
21 | + /// <summary> | |
22 | + /// 選択されているオブジェクトがVMDファイルかチェックします | |
23 | + /// </summary> | |
24 | + /// <returns>VMDファイルであればそのパスを、異なればnullを返します。</returns> | |
25 | + void setup() | |
26 | + { | |
27 | + var t = AssetDatabase.GetAssetPath(Selection.activeObject); | |
28 | + if (vmd_path != t) | |
29 | + { | |
30 | + if (!File.Exists(t)) return; | |
31 | + var config = MMD.Config.LoadAndCreate(); | |
32 | + | |
33 | + createAnimationFile = config.vmd_config.createAnimationFile; | |
34 | + interpolationQuality = config.vmd_config.interpolationQuality; | |
35 | + | |
36 | + // モデル情報 | |
37 | + vmd_path = t; | |
38 | + if (config.inspector_config.use_vmd_preload) | |
39 | + { | |
40 | + using (var fs = new FileStream(vmd_path, FileMode.Open, FileAccess.Read)) | |
41 | + using (var bin = new BinaryReader(fs)) | |
42 | + { | |
43 | + vmd_header = new MMD.VMD.VMDFormat.Header(bin); | |
44 | + } | |
45 | + } | |
46 | + else | |
47 | + { | |
48 | + vmd_header = null; | |
49 | + } | |
50 | + } | |
51 | + } | |
52 | + | |
53 | + /// <summary> | |
54 | + /// Inspector上のGUI描画処理を行います | |
55 | + /// </summary> | |
56 | + public override void OnInspectorGUI() | |
57 | + { | |
58 | + setup(); | |
59 | + | |
60 | + // GUIの有効化 | |
61 | + GUI.enabled = true; | |
62 | + | |
63 | + pmdPrefab = EditorGUILayout.ObjectField("PMD Prefab", pmdPrefab, typeof(Object), false) as GameObject; | |
64 | + createAnimationFile = EditorGUILayout.Toggle("Create Asset", createAnimationFile); | |
65 | + interpolationQuality = EditorGUILayout.IntSlider("Interpolation Quality", interpolationQuality, 1, 10); | |
66 | + | |
67 | + // Convertボタン | |
68 | + EditorGUILayout.Space(); | |
69 | + if (message.Length != 0) | |
70 | + { | |
71 | + GUILayout.Label(message); | |
72 | + } | |
73 | + else | |
74 | + { | |
75 | + if (GUILayout.Button("Convert")) | |
76 | + { | |
77 | + new VMDLoaderScript(target, pmdPrefab, createAnimationFile, interpolationQuality); | |
78 | + message = "Loading done."; | |
79 | + } | |
80 | + } | |
81 | + GUILayout.Space(40); | |
82 | + | |
83 | + // モデル情報 | |
84 | + if (vmd_header == null) return; | |
85 | + EditorGUILayout.LabelField("Model Name"); | |
86 | + GUI.enabled = false; | |
87 | + EditorGUILayout.TextArea(vmd_header.vmd_model_name); | |
88 | + GUI.enabled = true; | |
89 | + } | |
90 | + } | |
91 | +} |
@@ -0,0 +1,53 @@ | ||
1 | +// Inspectorからインポートなどができるようになります | |
2 | +// 他スクリプトと競合してしまう時はコメントアウトしてください | |
3 | + | |
4 | +#define USE_INSPECTOR | |
5 | + | |
6 | +//---------- | |
7 | + | |
8 | +#if USE_INSPECTOR | |
9 | +using System.IO; | |
10 | +using UnityEditor; | |
11 | +using UnityEngine; | |
12 | + | |
13 | +namespace MMD | |
14 | +{ | |
15 | + [CustomEditor(typeof(Object))] | |
16 | + public class InspectorBase : Editor | |
17 | + { | |
18 | + static Editor editor; | |
19 | + | |
20 | + public InspectorBase() | |
21 | + { | |
22 | + var ext = Path.GetExtension(AssetDatabase.GetAssetPath(Selection.activeObject)); | |
23 | + if (ext == ".pmd" || ext == ".pmx") | |
24 | + { | |
25 | + editor = Editor.CreateEditor(Selection.activeObject, typeof(PMDInspector)); | |
26 | + } | |
27 | + else if (ext == ".vmd") | |
28 | + { | |
29 | + editor = Editor.CreateEditor(Selection.activeObject, typeof(VMDInspector)); | |
30 | + } | |
31 | + else | |
32 | + { | |
33 | + editor = null; | |
34 | + } | |
35 | + } | |
36 | + | |
37 | + // Inspector上のGUI描画処理 | |
38 | + public override void OnInspectorGUI() | |
39 | + { | |
40 | + if (editor != null) | |
41 | + editor.OnInspectorGUI(); | |
42 | + } | |
43 | + | |
44 | + // Inspector上のPreviewエリア描画処理 | |
45 | + public override void OnPreviewGUI(Rect r, GUIStyle background) | |
46 | + { | |
47 | + if (editor != null) | |
48 | + editor.OnPreviewGUI(r, background); | |
49 | + } | |
50 | + } | |
51 | +} | |
52 | + | |
53 | +#endif |
@@ -0,0 +1,198 @@ | ||
1 | +using UnityEngine; | |
2 | +using UnityEditor; | |
3 | +using System; | |
4 | +using System.Collections.Generic; | |
5 | +using System.Linq; | |
6 | +using MMD.PMD; | |
7 | + | |
8 | +namespace MMD | |
9 | +{ | |
10 | + /// <summary> | |
11 | + /// MFU全体で必要そうなコンフィグ管理 | |
12 | + /// </summary> | |
13 | + [Serializable] | |
14 | + public class Config : ScriptableObject | |
15 | + { | |
16 | + public InspectorConfig inspector_config; | |
17 | + public DefaultPMDImportConfig pmd_config; | |
18 | + public DefaultVMDImportConfig vmd_config; | |
19 | + | |
20 | + private List<ConfigBase> update_list; | |
21 | + public void OnEnable() | |
22 | + { | |
23 | + // Inspectorで編集をさせない | |
24 | + hideFlags = HideFlags.NotEditable; | |
25 | + if (pmd_config == null) | |
26 | + { | |
27 | + // ここで初期化処理を書く | |
28 | + pmd_config = new DefaultPMDImportConfig(); | |
29 | + vmd_config = new DefaultVMDImportConfig(); | |
30 | + inspector_config = new InspectorConfig(); | |
31 | + } | |
32 | + if (update_list == null) | |
33 | + { | |
34 | + update_list = new List<ConfigBase>(); | |
35 | + update_list.Add(inspector_config); | |
36 | + update_list.Add(pmd_config); | |
37 | + update_list.Add(vmd_config); | |
38 | + } | |
39 | + } | |
40 | + | |
41 | + /// <summary> | |
42 | + /// GUI描画処理 | |
43 | + /// </summary> | |
44 | + public void OnGUI() | |
45 | + { | |
46 | + if (update_list == null) return; | |
47 | + update_list.ForEach((item) => | |
48 | + { | |
49 | + item.OnGUI(); | |
50 | + }); | |
51 | + } | |
52 | + | |
53 | + /// <summary> | |
54 | + /// MMDLoaderConfigが配置された場所から保存先を生成します | |
55 | + /// </summary> | |
56 | + /// <returns>アセット保存先のパス</returns> | |
57 | + public static string GetConfigPath() | |
58 | + { | |
59 | + var type = "Config"; | |
60 | + var path = AssetDatabase.GetAllAssetPaths().Where(item => item.Contains(type)).First(); | |
61 | + path = path.Substring(0, path.LastIndexOf('/') + 1) + type + ".asset"; | |
62 | + return path; | |
63 | + } | |
64 | + | |
65 | + /// <summary> | |
66 | + /// Config.assetを読み込みます。なかったら作ります。 | |
67 | + /// </summary> | |
68 | + /// <returns>読み込んで生成したConfigオブジェクト</returns> | |
69 | + public static Config LoadAndCreate() | |
70 | + { | |
71 | + var path = Config.GetConfigPath(); | |
72 | + var config = AssetDatabase.LoadAssetAtPath(path, typeof(Config)) as Config; | |
73 | + | |
74 | + //// なかったら作成する | |
75 | + if (config == null && !System.IO.File.Exists(path)) | |
76 | + { | |
77 | + config = CreateInstance<Config>(); | |
78 | + AssetDatabase.CreateAsset(config, path); | |
79 | + EditorUtility.SetDirty(config); | |
80 | + } | |
81 | + return config; | |
82 | + } | |
83 | + } | |
84 | + | |
85 | + /// <summary> | |
86 | + ///インスペクタのコンフィグ | |
87 | + /// </summary> | |
88 | + [Serializable] | |
89 | + public class InspectorConfig : ConfigBase | |
90 | + { | |
91 | + public bool use_pmd_preload = false; | |
92 | + public bool use_vmd_preload = false; | |
93 | + | |
94 | + public InspectorConfig() | |
95 | + { | |
96 | + this.title = "Inspector Config"; | |
97 | + } | |
98 | + | |
99 | + public override void OnGUI() | |
100 | + { | |
101 | + base.OnGUI(() => | |
102 | + { | |
103 | + use_pmd_preload = EditorGUILayout.Toggle("Use PMD Preload", use_pmd_preload); | |
104 | + use_vmd_preload = EditorGUILayout.Toggle("Use VMD Preload", use_vmd_preload); | |
105 | + } | |
106 | + ); | |
107 | + } | |
108 | + } | |
109 | + | |
110 | + /// <summary> | |
111 | + /// PMDインポートのデフォルトコンフィグ | |
112 | + /// </summary> | |
113 | + [Serializable] | |
114 | + public class DefaultPMDImportConfig : ConfigBase | |
115 | + { | |
116 | + public ShaderType shader_type = ShaderType.MMDShader; | |
117 | + public bool use_mecanim = false; | |
118 | + public bool rigidFlag = true; | |
119 | + public bool use_ik = true; | |
120 | + | |
121 | + public DefaultPMDImportConfig() | |
122 | + { | |
123 | + this.title = "Default PMD Import Config"; | |
124 | + } | |
125 | + | |
126 | + public override void OnGUI() | |
127 | + { | |
128 | + base.OnGUI(() => | |
129 | + { | |
130 | + shader_type = (ShaderType)EditorGUILayout.EnumPopup("Shader Type", shader_type); | |
131 | + rigidFlag = EditorGUILayout.Toggle("Rigidbody", rigidFlag); | |
132 | + use_mecanim = false; | |
133 | + use_ik = EditorGUILayout.Toggle("Use IK", use_ik); | |
134 | + } | |
135 | + ); | |
136 | + } | |
137 | + } | |
138 | + | |
139 | + /// <summary> | |
140 | + /// VMDインポートのデフォルトコンフィグ | |
141 | + /// </summary> | |
142 | + [Serializable] | |
143 | + public class DefaultVMDImportConfig : ConfigBase | |
144 | + { | |
145 | + public bool createAnimationFile; | |
146 | + public int interpolationQuality; | |
147 | + | |
148 | + public DefaultVMDImportConfig() | |
149 | + { | |
150 | + this.title = "Default VMD Import Config"; | |
151 | + } | |
152 | + | |
153 | + public override void OnGUI() | |
154 | + { | |
155 | + base.OnGUI(() => | |
156 | + { | |
157 | + createAnimationFile = EditorGUILayout.Toggle("Create Asset", createAnimationFile); | |
158 | + interpolationQuality = EditorGUILayout.IntSlider("Interpolation Quality", interpolationQuality, 1, 10); | |
159 | + } | |
160 | + ); | |
161 | + } | |
162 | + } | |
163 | + | |
164 | + /// <summary> | |
165 | + /// コンフィグ用のベースクラスです | |
166 | + /// </summary> | |
167 | + public class ConfigBase | |
168 | + { | |
169 | + /// <summary> | |
170 | + /// このコンフィグのタイトルを指定します | |
171 | + /// </summary> | |
172 | + protected string title = ""; | |
173 | + | |
174 | + /// <summary> | |
175 | + /// 開け閉めの状態 | |
176 | + /// </summary> | |
177 | + private bool fold = true; | |
178 | + | |
179 | + /// <summary> | |
180 | + /// GUI処理を行います | |
181 | + /// </summary> | |
182 | + /// <param name="OnGUIFunction">引数・戻り値なしのラムダ式</param> | |
183 | + public void OnGUI(Action OnGUIFunction) | |
184 | + { | |
185 | + fold = EditorGUILayout.Foldout(fold, title); | |
186 | + if (fold) | |
187 | + OnGUIFunction(); | |
188 | + EditorGUILayout.Space(); | |
189 | + } | |
190 | + | |
191 | + /// <summary> | |
192 | + /// GUI処理を行います | |
193 | + /// </summary> | |
194 | + public virtual void OnGUI() | |
195 | + { | |
196 | + } | |
197 | + } | |
198 | +} |
@@ -0,0 +1,110 @@ | ||
1 | +using UnityEngine; | |
2 | +using UnityEditor; | |
3 | +using System.Collections; | |
4 | +using MMD.PMD; | |
5 | +using System.IO; | |
6 | + | |
7 | +namespace MMD | |
8 | +{ | |
9 | + public class PMDInspector : Editor | |
10 | + { | |
11 | + // PMD Load option | |
12 | + public ShaderType shader_type; | |
13 | + public bool rigidFlag; | |
14 | + public bool use_mecanim; | |
15 | + public bool use_ik; | |
16 | + | |
17 | + // last selected item | |
18 | + private static string pmd_path = ""; | |
19 | + private static MMD.PMD.PMDFormat.Header pmd_header; | |
20 | + private static string message = ""; | |
21 | + | |
22 | + /// <summary> | |
23 | + /// pmd_headerとデフォルトコンフィグの設定 | |
24 | + /// </summary> | |
25 | + private void setup() | |
26 | + { | |
27 | + var t = AssetDatabase.GetAssetPath(Selection.activeObject); | |
28 | + if (pmd_path != t) | |
29 | + { | |
30 | + if (!File.Exists(t)) return; | |
31 | + var config = MMD.Config.LoadAndCreate(); | |
32 | + | |
33 | + // デフォルトコンフィグ | |
34 | + shader_type = config.pmd_config.shader_type; | |
35 | + rigidFlag = config.pmd_config.rigidFlag; | |
36 | + use_mecanim = config.pmd_config.use_mecanim; | |
37 | + use_ik = config.pmd_config.use_ik; | |
38 | + | |
39 | + // モデル情報 | |
40 | + pmd_path = t; | |
41 | + if (config.inspector_config.use_pmd_preload) | |
42 | + { | |
43 | + using (var fs = new FileStream(pmd_path, FileMode.Open, FileAccess.Read)) | |
44 | + using (var bin = new BinaryReader(fs)) | |
45 | + { | |
46 | + pmd_header = new MMD.PMD.PMDFormat.Header(bin); | |
47 | + } | |
48 | + } | |
49 | + else | |
50 | + { | |
51 | + pmd_header = null; | |
52 | + } | |
53 | + } | |
54 | + if (EditorApplication.isPlaying) pmd_path = ""; | |
55 | + } | |
56 | + | |
57 | + /// <summary> | |
58 | + /// Inspector上のGUI描画処理を行います | |
59 | + /// </summary> | |
60 | + public override void OnInspectorGUI() | |
61 | + { | |
62 | + setup(); | |
63 | + | |
64 | + // GUIの有効化 | |
65 | + GUI.enabled = !EditorApplication.isPlaying; | |
66 | + | |
67 | + // シェーダの種類 | |
68 | + shader_type = (ShaderType)EditorGUILayout.EnumPopup("Shader Type", shader_type); | |
69 | + | |
70 | + // 剛体を入れるかどうか | |
71 | + rigidFlag = EditorGUILayout.Toggle("Rigidbody", rigidFlag); | |
72 | + | |
73 | + // Mecanimを使うかどうか | |
74 | + use_mecanim = EditorGUILayout.Toggle("Use Mecanim (not work)", use_mecanim); | |
75 | + | |
76 | + // IKを使うかどうか | |
77 | + use_ik = EditorGUILayout.Toggle("Use IK", use_ik); | |
78 | + | |
79 | + // Convertボタン | |
80 | + EditorGUILayout.Space(); | |
81 | + if (message.Length != 0) | |
82 | + { | |
83 | + GUILayout.Label(message); | |
84 | + } | |
85 | + else | |
86 | + { | |
87 | + if (GUILayout.Button("Convert to Prefab")) | |
88 | + { | |
89 | + new PMDLoaderScript(target, shader_type, rigidFlag, use_mecanim, use_ik); | |
90 | + message = "Loading done."; | |
91 | + } | |
92 | + } | |
93 | + GUILayout.Space(40); | |
94 | + | |
95 | + // モデル情報 | |
96 | + if (pmd_header == null) return; | |
97 | + EditorGUILayout.LabelField("Model Name"); | |
98 | + GUI.enabled = false; | |
99 | + EditorGUILayout.TextArea(pmd_header.model_name); | |
100 | + GUI.enabled = true; | |
101 | + | |
102 | + EditorGUILayout.Space(); | |
103 | + | |
104 | + EditorGUILayout.LabelField("Comment"); | |
105 | + GUI.enabled = false; | |
106 | + EditorGUILayout.TextArea(pmd_header.comment, GUILayout.Height(300)); | |
107 | + GUI.enabled = true; | |
108 | + } | |
109 | + } | |
110 | +} | |
\ No newline at end of file |