protected static List <Action <ConvertContext> > CreateConverterList() { return(new List <Action <ConvertContext> >() { ctx => { bool cnv = false; var shader = ctx.target.shader; while (WFCommonUtility.IsSupportedShader(shader) && !WFCommonUtility.IsMobileSupportedShader(shader)) { // シェーダ切り替え var fallback = WFCommonUtility.GetShaderFallBackTarget(shader) ?? "Hidden/UnlitWF/WF_UnToon_Hidden"; WFCommonUtility.ChangeShader(fallback, ctx.target); // シェーダ切り替え後に RenderQueue をコピー ctx.target.renderQueue = ctx.oldMaterial.renderQueue; shader = ctx.target.shader; cnv = true; } if (cnv) { WFCommonUtility.SetupShaderKeyword(ctx.target); EditorUtility.SetDirty(ctx.target); } }, ctx => { if (IsMatchShaderName(ctx.oldMaterial.shader, "Transparent3Pass") && !IsMatchShaderName(ctx.target.shader, "Transparent3Pass")) { // Transparent3Pass からそうではないシェーダの切り替えでは、_AL_ZWrite を ON に変更する ctx.target.SetInt("_AL_ZWrite", 1); } }, }); }
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 string[] GetExistingShaderKeywords(Shader shader, IList <ShaderCompilerData> data) { return(data.SelectMany(d => d.shaderKeywordSet.GetShaderKeywords()) .Where(k => ShaderKeyword.IsKeywordLocal(k)) .Select(k => ShaderKeyword.GetKeywordName(shader, k)) .Where(kwd => WFCommonUtility.IsEnableKeyword(kwd)).Distinct().ToArray()); }
public static bool IsEnableToggleFromPropName(string prop_name) { string label, name; WFCommonUtility.FormatPropName(prop_name, out label, out name); return(IsEnableToggle(label, name)); }
private static void Menu_DebugView() { foreach (var mat in MaterialSeeker.GetSelectionAllMaterial(MatSelectMode.FromAsset)) { WFCommonUtility.ChangeShader(WF_DebugViewEditor.SHADER_NAME_DEBUGVIEW, mat); } }
private static string SplitAndTranslate(string before) { if (WFCommonUtility.FormatDispName(before, out var label, out var text, out var _)) { // text がラベルとテキストに分割できるならば return("[" + label + "] " + Translate(label, text)); }
public static void PostChangeShader(Material material, Shader oldShader, Shader newShader) { if (material != null) { // DebugViewの保存に使っているタグはクリア WF_DebugViewEditor.ClearDebugOverrideTag(material); // 不要なシェーダキーワードは削除 foreach (var key in DELETE_KEYWORD) { if (material.IsKeywordEnabled(key)) { material.DisableKeyword(key); } } // もし EmissionColor の Alpha が 0 になっていたら 1 にしちゃう if (!WFCommonUtility.IsSupportedShader(oldShader) && material.HasProperty("_EmissionColor")) { var em = material.GetColor("_EmissionColor"); if (em.a < 1e-4) { em.a = 1.0f; material.SetColor("_EmissionColor", em); } } } }
public static string GetDisplayName(string text) { text = text ?? ""; var current = GetDict(); if (current == null) { return(text); // 無いなら変換しない } string ret; // text がラベルとテキストに分割できるならば if (WFCommonUtility.FormatDispName(text, out string label, out string name2, out ret)) { // ラベルとテキストが両方とも一致するものを最初に検索する ret = current.Where(t => t.ContainsTag(label) && t.Before == name2).Select(t => t.After).FirstOrDefault(); if (ret != null) { return("[" + label + "] " + ret); } // ラベルなしでテキストが一致するものを検索する ret = current.Where(t => t.HasNoTag() && t.Before == name2).Select(t => t.After).FirstOrDefault(); if (ret != null) { return("[" + label + "] " + ret); } //// ラベル問わずテキストが一致するものを検索する //ret = current.Where(t => t.Before == name2).Select(t => t.After).FirstOrDefault(); //if (ret != null) { // return "[" + label + "] " + ret; //} }
private static void ChangeFromMenu() { foreach (var mat in Selection.GetFiltered <Material>(SelectionMode.Assets)) { WFCommonUtility.ChangeShader(SHADER_NAME_DEBUGVIEW, mat); } }
private static IEnumerator Execute() { string rawText = localTestData; if (string.IsNullOrWhiteSpace(rawText)) { using (UnityWebRequest req = UnityWebRequest.Get(URI_VERSION_JSON)) { yield return(req.SendWebRequest()); if (req.isHttpError || req.isNetworkError) { Debug.LogWarningFormat("[WF][Version] An NetworkError was occured in version checking: {0}", req.error); yield break; } rawText = req.downloadHandler.text; } } if (string.IsNullOrWhiteSpace(rawText)) { yield break; } var version = new WFVersionInfo(); EditorJsonUtility.FromJsonOverwrite(rawText, version); if (version.HasValue()) { version.downloadPage = URI_HEAD + version.downloadPage; WFCommonUtility.SetLatestVersion(version); Debug.LogFormat("[WF][Version] VersionCheck Succeed, LatestVersion is {0}", version.latestVersion); } }
public static void copyProperties(CopyPropParameter param, bool undo) { if (param.materialSource == null) { return; } var src_props = new List <ShaderMaterialProperty>(); // Label経由とPrefix経由をどちらもPrefixにする var copy_target = new List <string>(WFShaderFunction.LabelToPrefix(param.labels.ToList())); copy_target.AddRange(param.prefixs); foreach (var src_prop in ShaderMaterialProperty.AsList(param.materialSource)) { string prefix = WFCommonUtility.GetPrefixFromPropName(src_prop.Name); if (prefix == null) { continue; } // Prefixの一致判定 if (copy_target.Any(prefix.Contains)) { if (!param.withoutTextures || src_prop.Type != ShaderUtil.ShaderPropertyType.TexEnv) { src_props.Add(src_prop); } } } if (src_props.Count == 0) { return; } if (undo) { Undo.RecordObjects(param.materialDestination, "WF copy materials"); } for (int i = 0; i < param.materialDestination.Length; i++) { var dst = param.materialDestination[i]; if (dst == null || dst == param.materialSource) { // コピー先とコピー元が同じ時もコピーしない continue; } var dst_props = ShaderMaterialProperty.AsDict(dst); // コピー if (CopyProperties(src_props, dst_props, param.onlyOverrideBuiltinTextures)) { // キーワードを整理する WFCommonUtility.SetupShaderKeyword(dst); // ダーティフラグを付ける EditorUtility.SetDirty(dst); } } AssetDatabase.SaveAssets(); }
public bool Contains(Material mat) { if (mat == null || !WFCommonUtility.IsSupportedShader(mat.shader)) { return(false); } return(_contains(this, mat)); }
public bool IsEnable(Material mat) { if (!WFCommonUtility.IsSupportedShader(mat)) { return(false); } return(_contains(this, mat)); }
private static bool Migration(Material mat) { if (!WFCommonUtility.IsSupportedShader(mat)) { return(false); } WFMaterialEditUtility.MigrationMaterialWithoutUndo(mat); return(true); }
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); } } } }
public static void CleanUpProperties(CleanUpParameter param) { Undo.RecordObjects(param.materials, "WF cleanup materials"); foreach (Material material in param.materials) { if (material == null) { continue; } var props = ShaderSerializedProperty.AsList(material); // 無効になってる機能のプレフィックスを集める var delPrefix = new List <string>(); foreach (var p in props) { string label, name; WFCommonUtility.FormatPropName(p.name, out label, out name); if (label != null && name.ToLower() == "enable" && p.FloatValue == 0) { delPrefix.Add(label); } } var del_props = new HashSet <ShaderSerializedProperty>(); // プレフィックスに合致する設定値を消去 Predicate <ShaderSerializedProperty> predPrefix = p => { string label = WFCommonUtility.GetPrefixFromPropName(p.name); return(label != null && delPrefix.Contains(label)); }; props.FindAll(predPrefix) // ただしEnableToggle自体は初期化しない .Where(p => !WFCommonUtility.IsEnableToggleFromPropName(p.name)).ToList().ForEach(p => del_props.Add(p)); // 未使用の値を削除 Predicate <ShaderSerializedProperty> predUnused = p => param.resetUnused && !p.HasPropertyInShader; props.FindAll(predUnused).ForEach(p => del_props.Add(p)); // 削除実行 DeleteProperties(del_props); // キーワードクリア if (param.resetKeywords) { foreach (var so in ShaderSerializedProperty.GetUniqueSerialObject(props)) { DeleteShaderKeyword(so); } } // キーワードを整理する WFCommonUtility.SetupShaderKeyword(material); // 反映 EditorUtility.SetDirty(material); } }
public static void MigrationMaterialWithoutUndo(params Material[] mats) { mats = mats.Where(m => !m.shader.name.Contains("MatcapShadows")).ToArray(); // プロパティ名を変更 var oldPropList = CreateRelacePropertyList(mats); RenamePropNameWithoutUndo(mats, oldPropList); // シェーダキーワードを整理 WFCommonUtility.SetupShaderKeyword(mats); }
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); } } } }
private void CleanupProperties() { foreach (Material material in materials) { if (material == null) { continue; } var so = new SerializedObject(material); so.Update(); var saved = so.FindProperty("m_SavedProperties"); // 無効になってる機能のプレフィックスを集める var delPrefix = new List <string>(); { var prop = saved.FindPropertyRelative("m_Floats"); foreach (var p in ToPropertyList(prop)) { string label, name; WFCommonUtility.FormatPropName(p.name, out label, out name); if (label != null && name.ToLower() == "enable" && p.value.floatValue == 0) { delPrefix.Add(label); } } } // プレフィックスに合致する設定値を消去 Predicate <ShaderPropertyView> predPrefix = p => { string label, name; WFCommonUtility.FormatPropName(p.name, out label, out name); return(label != null && delPrefix.Contains(label)); }; DeleteProperties(saved.FindPropertyRelative("m_Colors"), predPrefix); DeleteProperties(saved.FindPropertyRelative("m_TexEnvs"), predPrefix); DeleteProperties(saved.FindPropertyRelative("m_Floats"), predPrefix); // 未使用の値を削除 Predicate <ShaderPropertyView> predUnused = p => reset_unused && !material.HasProperty(p.name); DeleteProperties(saved.FindPropertyRelative("m_Colors"), predUnused); DeleteProperties(saved.FindPropertyRelative("m_Floats"), predUnused); DeleteProperties(saved.FindPropertyRelative("m_TexEnvs"), predUnused); // キーワードクリア if (reset_keywords) { DeleteShaderKeyword(so.FindProperty("m_ShaderKeywords")); } // 反映 so.ApplyModifiedProperties(); EditorUtility.SetDirty(material); } }
/// <summary> /// プロパティ物理名からラベル文字列を抽出する。特殊な名称は辞書を参照してラベル文字列を返却する。 /// </summary> /// <param name="prop_name"></param> /// <returns></returns> public static string GetPrefixFromPropName(string prop_name) { string label = WFShaderDictionary.SpecialPropNameToLabelMap.GetValueOrNull(prop_name); if (label != null) { return(label); } string name; WFCommonUtility.FormatPropName(prop_name, out label, out name); return(label); }
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); }
public void CopyProperties(CopyPropParameter param) { if (param.materialSource == null) { return; } var src_props = new List <ShaderMaterialProperty>(); var copy_target = WFShaderFunction.LabelToPrefix(param.functions.ToList()); foreach (var src_prop in ShaderMaterialProperty.AsList(param.materialSource)) { string label = WFCommonUtility.GetPrefixFromPropName(src_prop.Name); if (label == null) { continue; } // ラベルの一致判定 if (copy_target.Any(label.Contains)) { src_props.Add(src_prop); } } if (src_props.Count == 0) { return; } for (int i = 0; i < param.materialDestination.Length; i++) { var dst = param.materialDestination[i]; if (dst == null || dst == param.materialSource) // コピー先とコピー元が同じ時もコピーしない { continue; } var dst_props = ShaderMaterialProperty.AsDict(dst); // コピー if (CopyProperties(src_props, dst_props)) { EditorUtility.SetDirty(dst); } } AssetDatabase.SaveAssets(); }
public static void DeleteShaderKeyword(SerializedObject so) { var prop = so.FindProperty("m_ShaderKeywords"); if (prop == null || string.IsNullOrEmpty(prop.stringValue)) { return; } var keywords = prop.stringValue; keywords = string.Join(" ", keywords.Split(' ').Where(kwd => !WFCommonUtility.IsEnableKeyword(kwd)).OrderBy(kwd => kwd)); if (!string.IsNullOrWhiteSpace(keywords)) { UnityEngine.Debug.Log("[WF][Tool] Deleted Shaderkeyword: " + keywords); } prop.stringValue = ""; so.ApplyModifiedProperties(); }
private void CopyProperties(SerializedProperty src, SerializedProperty dst, List <string> prefix) { var dst_list = ToPropertyList(dst); foreach (var src_prop in ToPropertyList(src)) { string label, name; WFCommonUtility.FormatPropName(src_prop.name, out label, out name); if (label != null && prefix.Contains(label)) { var dst_prop = dst_list.Find(p => p.name == src_prop.name); if (dst_prop != null) { src_prop.CopyTo(dst_prop); } } } }
private static bool IsStripTargetShader(Shader shader) { if (shader == null) { return(false); } if (!WFCommonUtility.IsSupportedShader(shader)) { return(false); } if (shader.name.Contains("WF_DebugView")) { return(false); } if (shader.name.Contains("WF_UnToon_Hidden")) { return(false); } return(true); }
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 void AppendUsedShaderVariant(Material mat, Shader shader) { // マテリアルから _XX_ENABLE となっているキーワードを回収 IEnumerable <string> keywords = mat.shaderKeywords.Where(kwd => WFCommonUtility.IsEnableKeyword(kwd)); UsedShaderVariant usv = new UsedShaderVariant(shader.name, keywords); if (!usedShaderVariantList.Contains(usv)) { usedShaderVariantList.Add(usv); // 直接のシェーダではなく、そのフォールバックを利用できるならばそれも追加する if (settings == null || !settings.stripFallback) { var name = WFCommonUtility.GetShaderFallBackTarget(shader); var fallback = name == null ? null : Shader.Find(name); if (IsStripTargetShader(fallback)) { AppendUsedShaderVariant(mat, fallback); } } } }
public static string GetDisplayName(string text) { text = text ?? ""; Dictionary <string, string> current = GetDict(); if (current != null) { string ret; if (current.TryGetValue(text, out ret)) { return(ret); } string label, name2; if (WFCommonUtility.FormatDispName(text, out label, out name2, out ret)) { if (current.TryGetValue(name2, out ret)) { return("[" + label + "] " + ret); } } } return(text); }
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); }