void DoUpgrade() { var targets = m_MaterialEditor.targets.Where(e => e is Material).Cast <Material>().ToArray(); for (int i = 0; m_tags != null && i < m_tags.Count; ++i) { var tagdef = m_tags[i]; if (!String.IsNullOrEmpty(tagdef.upgradeTypename)) { var typename = tagdef.typename; tagdef.upgradeState = tagdef.upgradeState ?? new Dictionary <Material, UpgradeOPType>(); var opState = tagdef.upgradeState; for (int mi = 0; mi < targets.Length; ++mi) { var mat = targets[mi]; UpgradeOPType curOp; if (opState.TryGetValue(mat, out curOp) && curOp == UpgradeOPType.None) { // 已经处理过了 continue; } var value = mat.GetTag(typename, true); if (tagdef.upgradeOPType != UpgradeOPType.None) { if (tagdef.upgradeOPType == UpgradeOPType.Cut && tagdef.removeAble == false && IsOptionNone(value)) { // 剪切模式下,要升级的类型值已经用空值覆盖,跳过处理 // 这会导致一个问题就是:如果一个没有升级的Tag,但是其值原本就是空, // 这样会导致这个状态不会被拷贝到需要升级的目标中去 opState[mat] = UpgradeOPType.None; continue; } var upgradeTypename = tagdef.upgradeTypename; var upgradeType = m_tags.Find(item => item.typename == upgradeTypename); if (!String.IsNullOrEmpty(value) && upgradeType != null) { UpgradeTag(mat, tagdef, upgradeType); } continue; } // value 可能为空字符串,也可能是表示空的有效字符串如'None' var index = Array.IndexOf(tagdef.values, value); var newIndex = index; var fixTag = false; if (index == -1) { if (tagdef.builtin) { // 系统tag,如果当前tag值没在选项中,追加 if (!String.IsNullOrEmpty(value)) { Array.Resize(ref tagdef.values, tagdef.values.Length + 1); tagdef.values[tagdef.values.Length - 1] = value; newIndex = tagdef.values.Length - 1; } } else { newIndex = 0; if (!IsNullTagValue(value)) { // 非空值,没有在选项中找到,当作一次修复操作,需要提示用户 fixTag = true; } } } if (newIndex >= 0 && newIndex != index) { if (!tagdef.readOnly) { _SetOverrideTag(mat, typename, tagdef.values[newIndex], fixTag); } } } } } // tag清理 var tagMap = new Dictionary <String, String>(); for (int i = 0; i < targets.Length; ++i) { var target = targets[i]; if (ShaderGUIHelper.GetMaterialOverrideTags(target, ref tagMap)) { foreach (var tag in tagMap) { var def = m_tags.Find(e => e.typename == tag.Key); if (def == null && Array.IndexOf(BuiltinTags, tag.Key) < 0) { // 材质中有编辑器未定义的tag var removeAble = ShaderGUIHelper.IsTagRemoveable(target, tag.Key); if (removeAble != null && removeAble.Value) { target.SetOverrideTag(tag.Key, String.Empty); Debug.LogFormat("Remove Override Tag: {0}", tag.Key); EditorUtility.SetDirty(target); } } } } } }