using UnityEditor; using UnityEngine; namespace AllIn13DShader { public abstract class AbstractEffectDrawer { private const float HEIGHT_PER_LINE = 12.5f; protected string drawerID; protected PropertiesConfig propertiesConfig; protected AllIn13DEffectConfig effectConfig; protected AllIn13DShaderInspectorReferences references; protected int globalEffectIndex; public string ID { get { return drawerID; } } public AbstractEffectDrawer(AllIn13DShaderInspectorReferences references, PropertiesConfig propertiesConfig) { this.references = references; this.propertiesConfig = propertiesConfig; } public void Draw(PropertiesConfig propertiesConfig, AllIn13DEffectConfig effectConfig, int globalEffectIndex) { this.propertiesConfig = propertiesConfig; this.effectConfig = effectConfig; this.globalEffectIndex = globalEffectIndex; Draw(); } protected virtual void Draw() { bool isShaderVariant = references.IsShaderVariant(); bool areDependenciesMet = AreDependenciesMet(); bool isEffectAvailableOnGlobalConfig = references.effectsProfileCollection.generalProfile.IsEffectEnabled(effectConfig.effectName); bool isEffectAvailable = AllIn13DEffectConfig.IsEffectAvailable(effectConfig, references); bool groupEnabled = isEffectAvailable; if (!isShaderVariant) { groupEnabled = groupEnabled && areDependenciesMet && isEffectAvailableOnGlobalConfig; } //bool groupEnabled = areDependenciesMet && isEffectAvailable && isEffectAvailableOnGlobalConfig /*|| (references.isShaderVariant && isEnabledInEffectsProfile)*/; //bool disableGroup = !groupEnabled; EditorGUILayout.BeginHorizontal(); EditorGUI.BeginDisabledGroup(!groupEnabled); EffectPropertyDrawer.DrawMainProperty(globalEffectIndex, effectConfig, references, isEffectAvailable, isEffectAvailableOnGlobalConfig); EditorGUILayout.EndHorizontal(); bool isAnyPropertyVisible = IsAnyPropertyVisible(); if (isAnyPropertyVisible) { EditorGUILayout.BeginVertical(references.propertiesStyle); DrawExtraData(); DrawProperties(); EditorGUILayout.EndVertical(); } EditorGUI.EndDisabledGroup(); } private void DrawExtraData() { if (IsParentPropertyEnabled()) { string customMessage = effectConfig.GetCustomMessage(references.targetMatInfos); if (!string.IsNullOrEmpty(customMessage)) { EditorGUILayout.BeginHorizontal(); int numLines = EditorUtils.GetNumLines(customMessage); float heightField = numLines * HEIGHT_PER_LINE; if (!string.IsNullOrEmpty(effectConfig.docURL)) { if (GUILayout.Button("?", GUILayout.Width(heightField), GUILayout.Height(heightField))) { Application.OpenURL(effectConfig.docURL); } } EditorGUILayout.LabelField(customMessage, references.smallLabelStyle, GUILayout.Height(heightField)); EditorGUILayout.EndHorizontal(); } } } protected virtual void DrawProperties() { for (int i = 0; i < effectConfig.effectProperties.Count; i++) { EffectProperty effectProperty = effectConfig.effectProperties[i]; DrawProperty(effectProperty, string.Empty, true); } } protected virtual void DrawProperty(EffectProperty effectProperty) { DrawProperty(effectProperty, true); } protected virtual void DrawProperty(EffectProperty effectProperty, bool allowReset) { DrawProperty(effectProperty, string.Empty, allowReset); } protected virtual void DrawProperty(EffectProperty effectProperty, string labelPrefix, bool allowReset) { if (IsEffectPropertyVisible(effectProperty, references.targetMatInfos)) { EffectProperty.PropertyType propertyType = effectProperty.GetPropertyType(); MaterialProperty matProperty = references.matProperties[effectProperty.propertyIndex]; string propertyCustomValue = string.Empty; if(references.IsShaderVariant() && effectProperty.IsPropertyWithKeywords()) { int index = 0; bool isEnabled = references.IsEffectPropertyEnabled(effectProperty, ref index); if (isEnabled) { if (effectProperty.IsEnumProperty()) { propertyCustomValue = effectProperty.propertyKeywords[index]; } else { propertyCustomValue = string.Empty; } } } EffectPropertyDrawer.DrawProperty( materialProperty: matProperty, labelPrefix: labelPrefix, displayName: effectProperty.displayName, customValue: propertyCustomValue, allowReset: allowReset, isKeywordProperty: effectProperty.IsPropertyWithKeywords(), propertyType: effectProperty.GetPropertyType(), references: references); //EffectPropertyDrawer.DrawProperty(effectProperty, labelPrefix, effectProperty.displayName, allowReset, effectProperty.IsPropertyWithKeywords(), references); //EffectPropertyDrawer.DrawProperty(effectProperty, labelPrefix, allowReset, references); } } protected bool IsParentPropertyEnabled() { bool res = true; for (int matIdx = 0; matIdx < references.targetMatInfos.Length; matIdx++) { AbstractMaterialInfo targetMatInfo = references.targetMatInfos[matIdx]; bool thisMatParentPropertyEnabled = false; for (int kwIdx = 0; kwIdx < effectConfig.keywords.Count; kwIdx++) { string kw = effectConfig.keywords[kwIdx].keyword; if (targetMatInfo.IsKeywordEnabled(kw)) { thisMatParentPropertyEnabled = true; break; } } res = res && thisMatParentPropertyEnabled; } return res; } protected bool IsAnyPropertyVisible() { bool res = false; bool parentPropertyEnabled = IsParentPropertyEnabled(); if (parentPropertyEnabled) { for (int propIdx = 0; propIdx < effectConfig.effectProperties.Count; propIdx++) { EffectProperty effectProperty = effectConfig.effectProperties[propIdx]; res = IsEffectPropertyVisible(effectProperty, references.targetMatInfos); if (res) { break; } } } res = res || (parentPropertyEnabled && !string.IsNullOrEmpty(effectConfig.GetCustomMessage(references.targetMatInfos))); return res; } protected bool IsEffectPropertyVisible(EffectProperty effectProperty, AbstractMaterialInfo[] targetMatInfos) { bool res = true; for (int i = 0; i < targetMatInfos.Length; i++) { res = res && IsEffectPropertyVisible(effectProperty, targetMatInfos[i]); } return res; } protected bool IsEffectPropertyVisible(EffectProperty effectProperty, AbstractMaterialInfo targetMatInfo) { bool res = false; bool anyIncompatibilities = false; for (int i = 0; i < effectProperty.incompatibleKeywords.Count; i++) { string incompatibleKw = effectProperty.incompatibleKeywords[i]; if (targetMatInfo.IsKeywordEnabled(incompatibleKw)) { anyIncompatibilities = true; } } if (!anyIncompatibilities) { if (effectProperty.keywordsOp == KeywordsOp.OR) { for (int i = 0; i < effectProperty.keywords.Count; i++) { string keyword = effectProperty.keywords[i]; if (targetMatInfo.IsKeywordEnabled(keyword)) { res = true; break; } } } else { res = true; for (int i = 0; i < effectProperty.keywords.Count; i++) { string keyword = effectProperty.keywords[i]; if (!targetMatInfo.IsKeywordEnabled(keyword)) { res = false; break; } } } } return res; } protected MaterialProperty FindPropertyByName(string propertyName) { MaterialProperty res = null; for (int i = 0; i < references.matProperties.Length; i++) { if (references.matProperties[i].name == propertyName) { res = references.matProperties[i]; break; } } return res; } protected int FindPropertyIndex(string propertyName) { int res = -1; for (int i = 0; i < references.matProperties.Length; i++) { if (references.matProperties[i].name == propertyName) { res = i; break; } } return res; } protected bool AreDependenciesMet() { bool res = true; if (!string.IsNullOrEmpty(effectConfig.dependentOnEffect)) { AllIn13DEffectConfig dependentEffect = propertiesConfig.FindEffectConfigByID(effectConfig.dependentOnEffect); res = res && AllIn13DEffectConfig.IsEffectEnabled(dependentEffect, references); } if (!string.IsNullOrEmpty(effectConfig.incompatibleWithEffectID)) { AllIn13DEffectConfig dependentEffect = propertiesConfig.FindEffectConfigByID(effectConfig.incompatibleWithEffectID); res = res && !AllIn13DEffectConfig.IsEffectEnabled(dependentEffect, references); } return res; } protected bool IsShaderVariant() { bool res = true; for(int i = 0; i < references.targetMatInfos.Length; i++) { if (references.targetMatInfos[i].IsShaderVariant()) { res = false; break; } } return res; } public virtual void Refresh(AllIn13DShaderInspectorReferences references) { this.references = references; } } }