Exemple #1
0
        public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
        {
            Material material  = materialEditor.target as Material;
            var      materials = materialEditor.targets.Cast <Material>();

            InitCachedPropGroups(properties, material);

            EditorGUI.BeginChangeCheck();
            DrawSelectionMode();
            var updateSelectionMode = EditorGUI.EndChangeCheck();

            string disabledPropHeader = "*";
            bool   insideBoxLayout    = false;

            _currentMaterialSelectedProps.Clear();
            _selectablePropertyCount = 0;
            string propHeader = null;

            foreach (var prop in properties)
            {
                if (prop.flags == MaterialProperty.PropFlags.HideInInspector || prop.flags == MaterialProperty.PropFlags.PerRendererData)
                {
                    continue;
                }

                if (_reflectionHelper.IsHeader(prop, material.shader))
                {
                    if (insideBoxLayout)
                    {
                        EditorGUILayout.Separator();
                        EditorGUILayout.EndVertical();
                        insideBoxLayout = false;
                    }

                    EditorGUILayout.BeginVertical(KamakuraInspectorUtility.BoxScopeStyle);
                    insideBoxLayout = true;
                }

                var  propFlagsHolder = _reflectionHelper.GetPropertyDrawer <MaterialKSFlagsDecorator>(prop, material.shader) ?? _defaultFlags;
                var  selectable      = !propFlagsHolder.IsFlagSet(KSFlags.NonSelectable);
                bool wasSelected     = false;

                if (propFlagsHolder.IsFlagSet(KSFlags.EnableFlag))
                {
                    if (!_cachedDisabledPropHeader.TryGetValue(prop.name, out propHeader))
                    {
                        propHeader = prop.name.Replace("_Enable", "_");
                        _cachedDisabledPropHeader[prop.name] = propHeader;
                    }
                    bool isParamPropEnabled = !Mathf.Approximately(prop.floatValue, 0f);
                    disabledPropHeader = isParamPropEnabled ? "*" : propHeader;
                }


                if (_selectPropertyMode && selectable)
                {
                    if (_selectionMode == SelectionMode.SelectAll)
                    {
                        _selectedProperties.Add(prop.name);
                    }
                    wasSelected = _selectedProperties.Contains(prop.name);
                    _selectablePropertyCount += 1;
                    if (wasSelected)
                    {
                        _currentMaterialSelectedProps.Add(prop.name);
                    }
                }


                var isDisabled = prop.name.StartsWith(disabledPropHeader, System.StringComparison.Ordinal);
                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);
                    }
                    if (isSelected != wasSelected && Event.current.alt)
                    {
                        UpdateSelectionPropsWithHeader(prop.name, properties, isSelected);
                    }
                    GUI.color = Color.white;
                }
                else
                {
                    EditorGUILayout.BeginHorizontal();
                }

                MaterialPropertyUtils.BeginChangeCheck(prop);
                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);
                }
                var propChanged = MaterialPropertyUtils.EndChangeCheck();

                if (propChanged && propFlagsHolder.IsFlagSet(KSFlags.AutoRenderQueue) && !prop.hasMixedValue && prop.floatValue > 0f)
                {
                    foreach (var mat in materials)
                    {
                        var blendMode = (KamakuraBlendMode)(int)mat.GetFloat("_BlendMode");
                        MaterialBlendModeUtils.SetMaterialBlendMode(mat, blendMode, true);
                    }
                }

                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();
                }
            }
        }
        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();
                }
            }
        }