using System; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UIElements; namespace UnityEditor.Rendering { /// /// Base implementation for drawing Default Volume Profile UI in Graphics Settings. /// public abstract class DefaultVolumeProfileSettingsPropertyDrawer : PropertyDrawer { VisualElement m_Root; DefaultVolumeProfileEditor m_Editor; /// SerializedObject representing the settings object protected SerializedObject m_SettingsSerializedObject; /// SerializedProperty representing the Default Volume Profile protected SerializedProperty m_VolumeProfileSerializedProperty; /// Foldout state protected EditorPrefBool m_DefaultVolumeProfileFoldoutExpanded; /// VisualElement containing the DefaultVolumeProfileEditor protected VisualElement m_EditorContainer; /// Default Volume Profile label width protected const int k_DefaultVolumeLabelWidth = 260; /// Info box message protected abstract GUIContent volumeInfoBoxLabel { get; } /// /// CreatePropertyGUI implementation. /// /// Property to create UI for /// VisualElement containing the created UI public override VisualElement CreatePropertyGUI(SerializedProperty property) { m_Root = new VisualElement(); var header = CreateHeader(); if (header != null) m_Root.Add(header); m_SettingsSerializedObject = property.serializedObject; m_VolumeProfileSerializedProperty = property.FindPropertyRelative("m_VolumeProfile"); m_DefaultVolumeProfileFoldoutExpanded = new EditorPrefBool($"{GetType()}.DefaultVolumeProfileFoldoutExpanded", true); m_EditorContainer = new VisualElement(); if (!RenderPipelineManager.pipelineSwitchCompleted) // Defer creation of the UI until the render pipeline is created and VolumeManager is initialized RenderPipelineManager.activeRenderPipelineCreated += CreateDefaultVolumeProfileEditor; else CreateDefaultVolumeProfileEditor(); m_Root.Add(CreateAssetFieldUI()); m_Root.Add(m_EditorContainer); return m_Root; } /// /// Creates the header for the Volume Profile editor. /// /// VisualElement containing the header. Null for no header. protected virtual VisualElement CreateHeader() => null; /// /// Creates the Default Volume Profile editor. /// protected void CreateDefaultVolumeProfileEditor() { RenderPipelineManager.activeRenderPipelineCreated -= CreateDefaultVolumeProfileEditor; VolumeProfile profile = m_VolumeProfileSerializedProperty.objectReferenceValue as VolumeProfile; if (profile == null) return; if (profile == VolumeManager.instance.globalDefaultProfile) VolumeProfileUtils.EnsureAllOverridesForDefaultProfile(profile); m_Editor = new DefaultVolumeProfileEditor(profile, m_SettingsSerializedObject); m_EditorContainer.Add(m_Editor.Create()); m_EditorContainer.Q("volume-override-info-box").text = volumeInfoBoxLabel.text; } /// /// Destroys the Default Volume Profile editor. /// protected void DestroyDefaultVolumeProfileEditor() { if (m_Editor != null) m_Editor.Destroy(); m_Editor = null; m_EditorContainer?.Clear(); } /// /// Implementation of the Default Volume Profile asset field. /// /// VisualElement containing the UI protected abstract VisualElement CreateAssetFieldUI(); /// /// Context menu implementation for Default Volume Profile. /// /// Default Volume Profile Settings type /// Render Pipeline type public abstract class DefaultVolumeProfileSettingsContextMenu : IRenderPipelineGraphicsSettingsContextMenu where TSetting : class, IDefaultVolumeProfileSettings where TRenderPipeline : RenderPipeline { /// /// Path where new Default Volume Profile will be created. /// protected abstract string defaultVolumeProfilePath { get; } void IRenderPipelineGraphicsSettingsContextMenu.PopulateContextMenu(TSetting setting, PropertyDrawer drawer, ref GenericMenu menu) { menu.AddSeparator(""); var volumeDrawer = drawer as DefaultVolumeProfileSettingsPropertyDrawer; bool canCreateNewAsset = RenderPipelineManager.currentPipeline is TRenderPipeline; VolumeProfileUtils.AddVolumeProfileContextMenuItems(ref menu, setting.volumeProfile, volumeDrawer.m_Editor.allEditors, overrideStateOnReset: true, defaultVolumeProfilePath: defaultVolumeProfilePath, onNewVolumeProfileCreated: createdProfile => { volumeDrawer.m_VolumeProfileSerializedProperty.objectReferenceValue = createdProfile; volumeDrawer.m_VolumeProfileSerializedProperty.serializedObject.ApplyModifiedProperties(); VolumeProfile initialAsset = null; var initialAssetSettings = EditorGraphicsSettings.GetRenderPipelineSettingsFromInterface(); if (initialAssetSettings.Length > 0) { if (initialAssetSettings.Length > 1) throw new InvalidOperationException("Found multiple settings implementing IDefaultVolumeProfileAsset, expected only one"); initialAsset = initialAssetSettings[0].defaultVolumeProfile; } VolumeProfileUtils.UpdateGlobalDefaultVolumeProfile(createdProfile, initialAsset); }, onComponentEditorsExpandedCollapsed: volumeDrawer.m_Editor.RebuildListViews, canCreateNewAsset); } } } }