using UnityEngine; using System.Collections.Generic; using UnityEngine.Serialization; using UnityEngine.UIElements; namespace UnityEditor.ShaderGraph { [FilePath("ProjectSettings/ShaderGraphSettings.asset", FilePathAttribute.Location.ProjectFolder)] internal class ShaderGraphProjectSettings : ScriptableSingleton { [SerializeField] internal int shaderVariantLimit = 2048; [SerializeField] internal int customInterpolatorErrorThreshold = 32; [SerializeField] internal int customInterpolatorWarningThreshold = 16; [SerializeField] internal ShaderGraphHeatmapValues customHeatmapValues; internal SerializedObject GetSerializedObject() { return new SerializedObject(this); } internal void Save() { Save(true); } private void OnDisable() { Save(); } public ShaderGraphHeatmapValues GetHeatValues() { return customHeatmapValues != null ? customHeatmapValues : ShaderGraphHeatmapValues.GetPackageDefault(); } } class ShaderGraphProjectSettingsProvider : SettingsProvider { private static int kMaxChannelThreshold = 32; private static int kMinChannelThreshold = 8; private static string kCustomInterpolatorHelpBox = "Unity uses these options to help Shader Graph users maintain known compatibilities with target platform(s) when using Custom Interpolators."; private static string kCustomInterpolatorDocumentationURL = UnityEngine.Rendering.ShaderGraph.Documentation.GetPageLink("Custom-Interpolators"); private class Styles { public static readonly GUIContent shaderVariantLimitLabel = L10n.TextContent("Shader Variant Limit", ""); public static readonly GUIContent CustomInterpLabel = L10n.TextContent("Custom Interpolator Channel Settings", ""); public static readonly GUIContent CustomInterpWarnThresholdLabel = L10n.TextContent("Warning Threshold", $"Shader Graph displays a warning when the user creates more custom interpolators than permitted by this setting. The number of interpolators that trigger this warning must be between {kMinChannelThreshold} and the Error Threshold."); public static readonly GUIContent CustomInterpErrorThresholdLabel = L10n.TextContent("Error Threshold", $"Shader Graph displays an error message when the user tries to create more custom interpolators than permitted by this setting. The number of interpolators that trigger this error must be between {kMinChannelThreshold} and {kMaxChannelThreshold}."); public static readonly GUIContent ReadMore = L10n.TextContent("Read more"); public static readonly GUIContent HeatmapSectionLabel = L10n.TextContent("Heatmap Color Mode Settings", ""); public static readonly GUIContent HeatmapAssetLabel = L10n.TextContent("Custom Values", "Specifies a custom Heatmap Values asset with data to display in the Heatmap color mode. If empty, a set of default values will be used."); } SerializedObject m_SerializedObject; SerializedProperty m_shaderVariantLimit; SerializedProperty m_customInterpWarn; SerializedProperty m_customInterpError; SerializedProperty m_HeatValues; public ShaderGraphProjectSettingsProvider(string path, SettingsScope scopes, IEnumerable keywords = null) : base(path, scopes, keywords) { guiHandler = OnGUIHandler; } public override void OnActivate(string searchContext, VisualElement rootElement) { ShaderGraphProjectSettings.instance.Save(); m_SerializedObject = ShaderGraphProjectSettings.instance.GetSerializedObject(); m_shaderVariantLimit = m_SerializedObject.FindProperty("shaderVariantLimit"); m_customInterpWarn = m_SerializedObject.FindProperty("customInterpolatorWarningThreshold"); m_customInterpError = m_SerializedObject.FindProperty("customInterpolatorErrorThreshold"); m_HeatValues = m_SerializedObject.FindProperty(nameof(ShaderGraphProjectSettings.customHeatmapValues)); } int oldWarningThreshold; void OnGUIHandler(string searchContext) { m_SerializedObject.Update(); EditorGUI.BeginChangeCheck(); var newVariantLimitValue = EditorGUILayout.DelayedIntField(Styles.shaderVariantLimitLabel, m_shaderVariantLimit.intValue); newVariantLimitValue = Mathf.Max(0, newVariantLimitValue); if (newVariantLimitValue != m_shaderVariantLimit.intValue) { m_shaderVariantLimit.intValue = newVariantLimitValue; if (ShaderGraphPreferences.onVariantLimitChanged != null) ShaderGraphPreferences.onVariantLimitChanged(); } EditorGUILayout.LabelField(Styles.CustomInterpLabel, EditorStyles.boldLabel); EditorGUI.indentLevel++; int newError = EditorGUILayout.IntField(Styles.CustomInterpErrorThresholdLabel, m_customInterpError.intValue); m_customInterpError.intValue = Mathf.Clamp(newError, kMinChannelThreshold, kMaxChannelThreshold); int oldWarn = m_customInterpWarn.intValue; int newWarn = EditorGUILayout.IntField(Styles.CustomInterpWarnThresholdLabel, m_customInterpWarn.intValue); // If the user did not modify the warning field, restore their previous input and reclamp against the new error threshold. if (oldWarn == newWarn) newWarn = oldWarningThreshold; else oldWarningThreshold = newWarn; m_customInterpWarn.intValue = Mathf.Clamp(newWarn, kMinChannelThreshold, m_customInterpError.intValue); GUILayout.BeginHorizontal(EditorStyles.helpBox); GUILayout.Label(EditorGUIUtility.IconContent("console.infoicon"), GUILayout.ExpandWidth(true)); GUILayout.Box(kCustomInterpolatorHelpBox, EditorStyles.wordWrappedLabel); if (EditorGUILayout.LinkButton(Styles.ReadMore)) { System.Diagnostics.Process.Start(kCustomInterpolatorDocumentationURL); } GUILayout.EndHorizontal(); EditorGUI.indentLevel--; EditorGUILayout.LabelField(Styles.HeatmapSectionLabel, EditorStyles.boldLabel); EditorGUI.indentLevel++; var oldHeatValues = (ShaderGraphHeatmapValues) m_HeatValues.objectReferenceValue; var newHeatValues = EditorGUILayout.ObjectField(Styles.HeatmapAssetLabel, oldHeatValues, typeof(ShaderGraphHeatmapValues), false); if (oldHeatValues != newHeatValues) { m_HeatValues.objectReferenceValue = newHeatValues; } EditorGUI.indentLevel--; if (EditorGUI.EndChangeCheck()) { m_SerializedObject.ApplyModifiedProperties(); ShaderGraphProjectSettings.instance.Save(); if (oldHeatValues != newHeatValues) { ShaderGraphHeatmapValuesEditor.UpdateShaderGraphWindows(); } } } [SettingsProvider] public static SettingsProvider CreateShaderGraphProjectSettingsProvider() { var provider = new ShaderGraphProjectSettingsProvider("Project/Shader Graph", SettingsScope.Project); return provider; } } }