/// <summary> /// 本来の順序で材質一覧の取得 /// </summary> /// <returns>材質一覧</returns> /// <param name='engine'>材質を取得するMMDEngine</param> static Material[] GetMaterials(MMDEngine engine) { SkinnedMeshRenderer[] renderers = engine.GetComponentsInChildren <SkinnedMeshRenderer>(); Material[] result = renderers.SelectMany(x => x.sharedMaterials).Distinct().ToArray(); if (1 < renderers.Length) { //rendererが複数有る(≒PMX)なら //PMXでは名前の先頭にはマテリアルインデックスが有るのでそれを参考にソート //PMDではrendererが1つしか無く、かつソート済みの為不要 System.Array.Sort(result, (x, y) => { string x_name = x.name.Substring(0, x.name.IndexOf('_')); string y_name = y.name.Substring(0, y.name.IndexOf('_')); int x_int, y_int; Int32.TryParse(x_name, out x_int); Int32.TryParse(y_name, out y_int); return(x_int - y_int); }); } return(result); }
/// <summary> /// 本来の順序で材質一覧の取得 /// </summary> /// <returns>材質一覧</returns> /// <param name='engine'>材質を取得するMMDEngine</param> static Material[] GetMaterials(MMDEngine engine) { SkinnedMeshRenderer[] renderers = engine.GetComponentsInChildren<SkinnedMeshRenderer>(); Material[] result = renderers.SelectMany(x=>x.sharedMaterials).Distinct().ToArray(); if (1 < renderers.Length) { //rendererが複数有る(≒PMX)なら //PMXでは名前の先頭にはマテリアルインデックスが有るのでそれを参考にソート //PMDではrendererが1つしか無く、かつソート済みの為不要 System.Array.Sort(result, (x,y)=>{ string x_name = x.name.Substring(0, x.name.IndexOf('_')); string y_name = y.name.Substring(0, y.name.IndexOf('_')); int x_int, y_int; Int32.TryParse(x_name, out x_int); Int32.TryParse(y_name, out y_int); return x_int - y_int; }); } return result; }
/// <summary> /// シェーダーリストの為のInspector描画 /// </summary> /// <returns>更新が有ったか(true:更新有り, false:未更新)</returns> private bool OnInspectorGUIforShaderList() { MMDEngine self = (MMDEngine)target; bool is_update = false; //シェーダーリストタイトル shader_display_ = EditorGUILayout.Foldout(shader_display_, "Shader List"); //シェーダーリスト内部 if (shader_display_) { //シェーダーリストを表示するなら SkinnedMeshRenderer[] renderers = self.GetComponentsInChildren <SkinnedMeshRenderer>(); Material[] materials = renderers.SelectMany(x => x.sharedMaterials).ToArray(); if (1 < renderers.Length) { //rendererが複数有る(≒PMX)なら //PMXでは名前の先頭にはマテリアルインデックスが有るのでそれを参考にソート //PMDではrendererが1つしか無く、かつソート済みの為不要 System.Array.Sort(materials, (x, y) => { string x_name = x.name.Substring(0, x.name.IndexOf('_')); string y_name = y.name.Substring(0, y.name.IndexOf('_')); int x_int, y_int; Int32.TryParse(x_name, out x_int); Int32.TryParse(y_name, out y_int); return(x_int - y_int); }); } GUIStyle style = new GUIStyle(); style.margin.left = 10; EditorGUILayout.BeginVertical(style); { //タイトル EditorGUILayout.BeginHorizontal(); { //ラベル EditorGUILayout.LabelField("Material", GUILayout.Width(64)); //シェーダー EditorGUILayout.LabelField(new GUIContent("Tr", "Transparent"), GUILayout.Width(20)); EditorGUILayout.LabelField(new GUIContent("Eg", "Edge"), GUILayout.Width(20)); EditorGUILayout.LabelField(new GUIContent("Rv", "Reversible"), GUILayout.Width(20)); EditorGUILayout.LabelField(new GUIContent("Cs", "CastShadow"), GUILayout.Width(20)); #if MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER //影受け無しのシェーダはまだ無いので無効化 EditorGUILayout.LabelField(new GUIContent("Rs", "ReceiveShadow"), GUILayout.Width(20)); #endif //MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER EditorGUILayout.LabelField("", GUILayout.Width(20)); EditorGUILayout.LabelField(new GUIContent("Hi", "Highlight"), GUILayout.Width(20)); EditorGUILayout.LabelField(new GUIContent("Hd", "Hidden"), GUILayout.Width(20)); } EditorGUILayout.EndHorizontal(); //描画用配列 var parameter_table = new[] { new { flag = ShaderFlag.Transparent, reverse = false } , new { flag = ShaderFlag.Outline, reverse = false } , new { flag = ShaderFlag.CullBack, reverse = true } //背景カリングON/OFFはわかり辛いので、MMDの様に両面描画ON/OFFで扱う , new { flag = ShaderFlag.NoCastShadow, reverse = true } //影放たないON/OFFの2重否定を止めて影放つON/OFFで扱う #if MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER //影受け無しのシェーダはまだ無いので無効化 , new { flag = ShaderFlag.NoReceiveShadow, reverse = true } //影受けないON/OFFの2重否定を止めて影受けるON/OFFで扱う #endif //MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER , new { flag = (ShaderFlag)0, reverse = false } , new { flag = ShaderFlag.Highlight, reverse = false } , new { flag = ShaderFlag.Hidden, reverse = false } }; //マテリアル int material_index = 0; foreach (var material in materials) { EditorGUILayout.BeginHorizontal(); { //ラベル EditorGUILayout.LabelField(new GUIContent((material_index++).ToString(), material.name), GUILayout.Width(64)); //シェーダー if (IsMmdShader(material)) { //MMDシェーダーなら bool is_change_shader = false; ShaderFlag flag = AnalyzeShaderFlag(material); foreach (var param in parameter_table) { if (0 != param.flag) { //描画用 bool enable_old = 0 != ((int)flag & (int)param.flag); if (param.reverse) { enable_old = !enable_old; } bool enable = EditorGUILayout.Toggle(enable_old, GUILayout.Width(20)); if (enable_old != enable) { //更新 if (param.reverse) { enable = !enable; } flag = (ShaderFlag)((int)flag ^ (int)param.flag); is_change_shader = true; } } else { //スペース用 EditorGUILayout.LabelField("", GUILayout.Width(20)); } } if (is_change_shader) { //変更が掛かったなら //Undo登録 Undo.RegisterUndo(material, "Shader Change"); SetShader(material, flag); is_update = true; } } } EditorGUILayout.EndHorizontal(); } } EditorGUILayout.EndVertical(); } return(is_update); }