void InitCachedPropGroups(MaterialProperty[] properties, Material material) { if (_cachedPropGroups != null) { return; } _cachedPropGroups = new Dictionary <string, HashSet <string> >(); HashSet <string> propGroup = null; foreach (var prop in properties) { if (prop.flags == MaterialProperty.PropFlags.HideInInspector || prop.flags == MaterialProperty.PropFlags.PerRendererData) { continue; } if (propGroup == null || _reflectionHelper.IsHeader(prop, material.shader)) { propGroup = new HashSet <string>(); } propGroup.Add(prop.name); _cachedPropGroups[prop.name] = propGroup; } }
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { Material material = materialEditor.target as Material; var materials = materialEditor.targets.Cast <Material>(); RichLabel = new GUIStyle(EditorStyles.boldLabel); RichLabel.richText = true; EditorGUI.BeginChangeCheck(); DrawSelectionMode(); var updateSelectionMode = EditorGUI.EndChangeCheck(); string disabledPropHeader = "N/A"; bool insideBoxLayout = false; _currentMaterialSelectedProps.Clear(); _selectablePropertyCount = 0; foreach (var prop in properties) { if (prop.flags == MaterialProperty.PropFlags.HideInInspector || prop.flags == MaterialProperty.PropFlags.PerRendererData) { continue; } string propHeader = null; if (_reflectionHelper.IsHeader(prop, material.shader)) { if (insideBoxLayout) { EditorGUILayout.Separator(); EditorGUILayout.EndVertical(); insideBoxLayout = false; } EditorGUILayout.BeginVertical(KamakuraInspectorUtility.BoxScopeStyle); insideBoxLayout = true; } if (_dict.TryGetValue(prop.name, out propHeader)) { bool isParamPropEnabled = !Mathf.Approximately(prop.floatValue, 0f); disabledPropHeader = isParamPropEnabled ? "N/A" : propHeader; } var selectable = prop.name != "_ShaderVersion"; bool wasSelected = false; bool selectAll = _selectionMode == SelectionMode.SelectAll; if (_selectPropertyMode && selectable) { if (selectAll) { _selectedProperties.Add(prop.name); } wasSelected = _selectedProperties.Contains(prop.name); _selectablePropertyCount += 1; if (wasSelected) { _currentMaterialSelectedProps.Add(prop.name); } } var isDisabled = prop.name.StartsWith(disabledPropHeader); if (isDisabled) { continue; } if (_selectPropertyMode && selectable) { GUI.color = wasSelected ? Color.green : Color.white; EditorGUILayout.BeginHorizontal(KamakuraInspectorUtility.SmallBoxScopeStyle); bool isSelected = EditorGUILayout.Toggle(wasSelected, EditorStyles.radioButton, GUILayout.MaxWidth(20), GUILayout.ExpandHeight(true)); if (isSelected) { _selectedProperties.Add(prop.name); } else { _selectedProperties.Remove(prop.name); } GUI.color = Color.white; } else { EditorGUILayout.BeginHorizontal(); } if (prop.name.Contains("UseCubeColor")) { var disabled = materials.Any(m => m.GetFloat("_EnableCubeColor") == 0); using (new EditorGUI.DisabledGroupScope(disabled)) { materialEditor.ShaderProperty(prop, prop.displayName); } } else { materialEditor.ShaderProperty(prop, prop.displayName); } EditorGUILayout.EndHorizontal(); // TODO find better way to display this description if (prop.name.Contains("_CubeColor5")) { EditorGUILayout.Separator(); EditorGUILayout.LabelField("CubeColor works on world space by default."); EditorGUILayout.LabelField("Attach a CubeColorLocalSpaceRoot component"); EditorGUILayout.LabelField("to make it works locally relative to the root."); } } if (insideBoxLayout) { EditorGUILayout.Separator(); EditorGUILayout.EndVertical(); insideBoxLayout = false; } materialEditor.RenderQueueField(); materialEditor.EnableInstancingField(); if (updateSelectionMode) { if (_selectionMode == SelectionMode.Copy) { _copiedProperties.Clear(); foreach (var propName in _currentMaterialSelectedProps) { var prop = properties.FirstOrDefault(p => p.name == propName); if (prop != null) { _copiedProperties[propName] = prop; } else { Debug.LogWarning("Could not copy property " + propName + " from current material"); } } } else if (_selectionMode == SelectionMode.Paste) { foreach (var selectedPropName in _selectedProperties) { MaterialProperty copiedProp; if (_copiedProperties.TryGetValue(selectedPropName, out copiedProp)) { var targetProp = properties.FirstOrDefault(p => p.name == selectedPropName); if (targetProp == null) { Debug.LogWarning("Could not paste copied property " + selectedPropName + " to current material"); continue; } targetProp.floatValue = copiedProp.floatValue; targetProp.colorValue = copiedProp.colorValue; targetProp.vectorValue = copiedProp.vectorValue; targetProp.textureValue = copiedProp.textureValue; targetProp.textureScaleAndOffset = copiedProp.textureScaleAndOffset; _reflectionHelper.ApplyMaterialPropertyHandler(targetProp, material.shader); } } } else if (_selectionMode == SelectionMode.Clear) { _selectedProperties.Clear(); _copiedProperties.Clear(); } } }