private static void OnGuiSub_SwitchPrevShaderButton(MaterialEditor materialEditor) { // 編集中のマテリアルの配列 var mats = WFCommonUtility.AsMaterials(materialEditor.targets); // PrevShader タグを持っているものがひとつでもあればボタン表示 if (mats.Select(m => m.GetTag(TAG_PREV_SHADER, false)).Any(tag => !string.IsNullOrWhiteSpace(tag))) { if (GUI.Button(EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()), "Switch Prev Shader")) { // 元のシェーダに戻す Undo.RecordObjects(mats, "change shader"); // それぞれのマテリアルに設定された PrevShader へと切り替え foreach (var mat in mats) { var name = mat.GetTag(TAG_PREV_SHADER, false); var queue = mat.GetTag(TAG_PREV_QUEUE, false); // DebugViewの保存に使っているタグはクリア ClearDebugOverrideTag(mat); // シェーダ切り替え WFCommonUtility.ChangeShader(name, mat); // queue戻し if (queue != null && int.TryParse(queue, out int numQueue)) { mat.renderQueue = numQueue; } } } EditorGUILayout.Space(); } }
private void OnGuiSub_ShowCurrentShaderName(MaterialEditor materialEditor, Material mat) { // シェーダ名の表示 var rect = EditorGUILayout.GetControlRect(); rect.y += 2; GUI.Label(rect, "Current Shader", EditorStyles.boldLabel); GUILayout.Label(new Regex(@".*/").Replace(mat.shader.name, "")); for (int idx = ShaderUtil.GetPropertyCount(mat.shader) - 1; 0 <= idx; idx--) { if ("_CurrentVersion" == ShaderUtil.GetPropertyName(mat.shader, idx)) { rect = EditorGUILayout.GetControlRect(); rect.y += 2; GUI.Label(rect, "Current Version", EditorStyles.boldLabel); GUILayout.Label(ShaderUtil.GetPropertyDescription(mat.shader, idx)); break; } } // シェーダ切り替えボタン var snm = WFShaderNameDictionary.TryFindFromName(mat.shader.name); if (snm != null) { var targets = WFCommonUtility.AsMaterials(materialEditor.targets); rect = EditorGUILayout.GetControlRect(); rect.y += 2; GUI.Label(rect, "Current Shader Variants", EditorStyles.boldLabel); // バリアント { var variants = WFShaderNameDictionary.GetVariantList(snm); var labels = variants.Select(nm => nm.Variant).ToArray(); int idx = Array.IndexOf(labels, snm.Variant); EditorGUI.BeginChangeCheck(); int select = EditorGUILayout.Popup("Variant", idx, labels); if (EditorGUI.EndChangeCheck() && idx != select) { WFCommonUtility.ChangeShader(variants[select].Name, targets); } } // Render Type { var variants = WFShaderNameDictionary.GetRenderTypeList(snm); var labels = variants.Select(nm => nm.RenderType).ToArray(); int idx = Array.IndexOf(labels, snm.RenderType); EditorGUI.BeginChangeCheck(); int select = EditorGUILayout.Popup("RenderType", idx, labels); if (EditorGUI.EndChangeCheck() && idx != select) { WFCommonUtility.ChangeShader(variants[select].Name, targets); } } } }
private static void OnGUISub_BatchingStaticHelpBox(MaterialEditor materialEditor) { // 現在のシェーダが DisableBatching == False のとき以外は何もしない (Batching されないので) var target = materialEditor.target as Material; if (target == null || !target.GetTag("DisableBatching", false, "False").Equals("False", StringComparison.OrdinalIgnoreCase)) { return; } // ターゲットが設定用プロパティをどちらも持っていないならば何もしない if (!target.HasProperty("_GL_DisableBackLit") && !target.HasProperty("_GL_DisableBasePos")) { return; } // 現在のシェーダ var shader = target.shader; // 現在編集中のマテリアルの配列 var targets = WFCommonUtility.AsMaterials(materialEditor.targets); // 現在編集中のマテリアルのうち、Batching Static のときにオンにしたほうがいい設定がオフになっているマテリアル var allNonStaticMaterials = targets.Where(mat => mat.GetInt("_GL_DisableBackLit") == 0 || mat.GetInt("_GL_DisableBasePos") == 0).ToArray(); if (allNonStaticMaterials.Length == 0) { return; } var scene = UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene(); // 現在のシーンにある BatchingStatic の付いた MeshRenderer が使っているマテリアルのうち、このShaderGUIが扱うマテリアルの配列 var allStaticMaterialsInScene = scene.GetRootGameObjects() .SelectMany(go => go.GetComponentsInChildren <MeshRenderer>(true)) .Where(mf => GameObjectUtility.AreStaticEditorFlagsSet(mf.gameObject, StaticEditorFlags.BatchingStatic)) .SelectMany(mf => mf.sharedMaterials) .Where(mat => mat != null && mat.shader == shader) .ToArray(); // Batching Static の付いているマテリアルが targets 内にあるならば警告 if (allNonStaticMaterials.Any(mat => allStaticMaterialsInScene.Contains(mat))) { var message = WFI18N.LangMode == EditorLanguage.日本語 ? "このマテリアルは Batching Static な MeshRenderer から使われているようです。Batching Static 用の設定へ変更しますか?" : "This material seems to be used by the Batching Static MeshRenderer. Do you want to change the settings for Batching Static?"; if (materialEditor.HelpBoxWithButton(new GUIContent(message, Styles.infoIcon), new GUIContent("Fix Now"))) { // _GL_DisableBackLit と _GL_DisableBasePos をオンにする foreach (var mat in allNonStaticMaterials) { mat.SetInt("_GL_DisableBackLit", 1); mat.SetInt("_GL_DisableBasePos", 1); } } } }
public void SetActive(Material[] targets) { foreach (var mat in WFCommonUtility.AsMaterials(targets)) { // リセット foreach (var p in ShaderMaterialProperty.AsList(mat).Where(p => p.Name.StartsWith("_Mode"))) { mat.SetInt(p.Name, 0); } // セット mat.SetInt(propertyName, value); } }
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { materialEditor.SetDefaultGUIWidths(); // 元シェーダに戻すボタン OnGuiSub_SwitchPrevShaderButton(materialEditor); var mat = materialEditor.target as Material; var mats = WFCommonUtility.AsMaterials(materialEditor.targets); // モード変更メニュー表示 foreach (var section in sections) { GUI.Label(EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()), section.name, EditorStyles.boldLabel); foreach (var mode in section.modes) { bool active = mode.IsActive(mat); EditorGUI.showMixedValue = mode.IsMixedValue(mats); EditorGUI.BeginChangeCheck(); active = EditorGUILayout.Toggle(mode.displayName, active); if (EditorGUI.EndChangeCheck()) { mode.SetActive(mats); } EditorGUI.showMixedValue = false; } EditorGUILayout.Space(); } // モード変更以外のプロパティを表示 foreach (var p in properties) { if (!p.name.StartsWith("_Mode")) { materialEditor.ShaderProperty(p, p.displayName); } } EditorGUILayout.Space(); GUI.Label(EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()), "Advanced Options", EditorStyles.boldLabel); materialEditor.RenderQueueField(); materialEditor.EnableInstancingField(); EditorGUILayout.Space(); // 一番下にも、元シェーダに戻すボタンを置く OnGuiSub_SwitchPrevShaderButton(materialEditor); }
private void OnGUISub_MigrationHelpBox(MaterialEditor materialEditor) { var mats = WFCommonUtility.AsMaterials(materialEditor.targets); if (IsOldMaterial(mats)) { var message = WFI18N.LangMode == EditorLanguage.日本語 ? "このマテリアルは古いバージョンで作成されたようです。最新版に変換しますか?" : "This Material may have been created in an older version. Convert to new version?"; if (materialEditor.HelpBoxWithButton(new GUIContent(message, Styles.warnIcon), new GUIContent("Fix Now"))) { var editor = new WFMaterialEditUtility(); // 名称を全て変更 editor.RenameOldNameProperties(mats); // リセット ResetOldMaterialTable(mats); } } }
private Dictionary <ShaderSerializedProperty, ShaderSerializedProperty> CreateOldNamePropertyList(UnityEngine.Object[] objlist) // ShaderCustomEditor側から呼び出されるのでobject[] { var result = new Dictionary <ShaderSerializedProperty, ShaderSerializedProperty>(); foreach (var mat in WFCommonUtility.AsMaterials(objlist)) { if (mat.shader.name.Contains("MatcapShadows")) { // MatcapShadowsは古いので対象にしない continue; } var props = ShaderSerializedProperty.AsDict(mat); foreach (var pair in WFShaderDictionary.OldPropNameToNewPropNameMap) { var before = props.GetValueOrNull(pair.Key); if (before != null) { result[before] = props.GetValueOrNull(pair.Value); } } } return(result); }
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { materialEditor.SetDefaultGUIWidths(); Material mat = materialEditor.target as Material; if (mat != null) { // CurrentShader OnGuiSub_ShowCurrentShaderName(materialEditor, mat); // マイグレーションHelpBox OnGUISub_MigrationHelpBox(materialEditor); // Batching Static対策HelpBox OnGUISub_BatchingStaticHelpBox(materialEditor); } // 現在無効なラベルを保持するリスト var disable = new HashSet <string>(); // プロパティを順に描画 foreach (var prop in properties) { // ラベル付き displayName を、ラベルと名称に分割 string label, name, disp; WFCommonUtility.FormatDispName(prop.displayName, out label, out name, out disp); // ラベルが指定されていてdisableに入っているならばスキップ(ただしenable以外) if (label != null && disable.Contains(label) && !WFCommonUtility.IsEnableToggle(label, name)) { continue; } // _TS_1stColorの直前にボタンを追加する if (prop.name == "_TS_1stColor") { Rect position = EditorGUILayout.GetControlRect(true, 24); Rect fieldpos = EditorGUI.PrefixLabel(position, WFI18N.GetGUIContent("[SH] Shade Color Suggest", "ベース色をもとに1影2影色を設定します")); fieldpos.height = 20; if (GUI.Button(fieldpos, "APPLY")) { SuggestShadowColor(WFCommonUtility.AsMaterials(materialEditor.targets)); } } // HideInInspectorをこのタイミングで除外するとFix*Drawerが動作しないのでそのまま通す // 非表示はFix*Drawerが担当 // Fix*Drawerと一緒にHideInInspectorを付けておけば、このcsが無い環境でも非表示のまま変わらないはず // if ((prop.flags & MaterialProperty.PropFlags.HideInInspector) != MaterialProperty.PropFlags.None) { // continue; // } // 更新監視 EditorGUI.BeginChangeCheck(); // 描画 OnGuiSub_ShaderProperty(materialEditor, properties, prop); // 更新監視 if (EditorGUI.EndChangeCheck()) { foreach (var setter in DEF_VALUE_SETTER) { setter(prop, properties); } } // ラベルが指定されていてenableならば有効無効をリストに追加 // このタイミングで確認する理由は、ShaderProperty内でFix*Drawerが動作するため if (WFCommonUtility.IsEnableToggle(label, name)) { if ((int)prop.floatValue == 0) { disable.Add(label); } else { disable.Remove(label); } } } DrawShurikenStyleHeader(EditorGUILayout.GetControlRect(false, 32), "Advanced Options", null); materialEditor.RenderQueueField(); materialEditor.EnableInstancingField(); //materialEditor.DoubleSidedGIField(); WFI18N.LangMode = (EditorLanguage)EditorGUILayout.EnumPopup("Editor language", WFI18N.LangMode); // 不要なシェーダキーワードは削除 foreach (object t in materialEditor.targets) { Material mm = t as Material; if (mm != null) { foreach (var key in DELETE_KEYWORD) { if (mm.IsKeywordEnabled(key)) { mm.DisableKeyword(key); } } } } }
public bool IsMixedValue(Material[] targets) { return(WFCommonUtility.AsMaterials(targets).Select(mat => IsActive(mat)).Distinct().Count() == 2); }