using System; using System.Reflection; using UnityEditor.Overlays; using System.Collections.Generic; using UnityEditorInternal; using UnityEditor.Snap; using UnityEngine; using UnityEditor.Toolbars; using UnityEditor; using UnityEngine.UIElements; using FrameCapture = UnityEngine.Apple.FrameCapture; using FrameCaptureDestination = UnityEngine.Apple.FrameCaptureDestination; using UnityEngine.Rendering.Universal; namespace SLZ.SLZEditorTools { [EditorToolbarElement(elementID, typeof(SceneView))] public class SceneViewVolumetricToggle : EditorToolbarToggle, IAccessContainerWindow { public const string elementID = VolumetricEditorToolbar.overlayID + "/Volumetrics"; public EditorWindow containerWindow { get; set; } SceneView sceneView => containerWindow as SceneView; public SceneViewVolumetricToggle() { var content = EditorGUIUtility.TrTextContentWithIcon("", "Unknown", "d_preAudioAutoPlayOff"); name = elementID; text = content.text; icon = content.image as Texture2D; tooltip = L10n.Tr("When toggled on, the Scene is in 2D view. When toggled off, the Scene is in 3D view."); this.RegisterValueChangedCallback(OnValueChanged); RegisterCallback<AttachToPanelEvent>(OnAttachedToPanel); RegisterCallback<DetachFromPanelEvent>(OnDetachFromPanel); //Type reflType = Type.GetType("UnityEditor.Toolbars.SceneViewToolbarElements, UnityEditor.UIServiceModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"); //if (reflType != null) //{ // MethodInfo reflMethod = reflType.GetMethod("AddStyleSheets", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); // if (reflMethod != null) // { // reflMethod.Invoke(null, new object[1] { this }); // } // else // { // Debug.Log("Could not find method"); // } //} //else //{ // Debug.Log("Could not find class"); //} } void OnValueChanged(ChangeEvent<bool> evt) { Camera sceneCam = sceneView.camera; VolumetricRendering vR = VolumetricPool.Instance.GetSceneVol(sceneCam); vR.enableEditorPreview = evt.newValue; if (evt.newValue) { vR.enabled = true; vR.enable(); vR.StartSceneViewRendering(); } else { vR.disable(); vR.enabled = false; } } void OnAttachedToPanel(AttachToPanelEvent evt) { value = sceneView.in2DMode; //sceneView.modeChanged2D += OnModeChanged; } void OnDetachFromPanel(DetachFromPanelEvent evt) { //sceneView.modeChanged2D -= OnModeChanged; } void OnModeChanged(bool enabled) { value = enabled; } } // IconAttribute provides a way to define an icon for when an Overlay is in collapsed form. If not provided, the name initials are used. //[Icon("Assets/unity.png")] // Toolbar Overlays must inherit `ToolbarOverlay` and implement a parameter-less constructor. The contents of a toolbar are populated with string IDs, which are passed to the base constructor. IDs are defined by EditorToolbarElementAttribute. [Overlay(typeof(SceneView), overlayID, "Volumetric Toggle", true)] public class VolumetricEditorToolbar : ToolbarOverlay { public const string overlayID = "VolumetricsToolbar"; // ToolbarOverlay implements a parameterless constructor, passing the EditorToolbarElementAttribute ID. // This is the only code required to implement a toolbar Overlay. Unlike panel Overlays, the contents are defined // as standalone pieces that will be collected to form a strip of elements. VolumetricEditorToolbar() : base( SceneViewVolumetricToggle.elementID ) { } } public class VolumetricPool : MonoBehaviour { static VolumetricPool s_Instance; public static VolumetricPool Instance { get { if (s_Instance == null) { GameObject volPool = new GameObject(); volPool.hideFlags = HideFlags.DontSave; volPool.name = "SceneViewVolumetricRendererPool"; s_Instance = volPool.AddComponent<VolumetricPool>(); } return s_Instance; } } public Dictionary<Camera, VolumetricRendering> SceneToVol; [ExecuteInEditMode] private void Awake() { SceneToVol = new Dictionary<Camera, VolumetricRendering>(); } private void OnDestroy() { foreach (KeyValuePair<Camera, VolumetricRendering> kvp in SceneToVol) { DestroyImmediate(kvp.Value.gameObject); } } public VolumetricRendering GetSceneVol(Camera sceneCam) { if (sceneCam != null) { VolumetricRendering vol; if (SceneToVol == null) { SceneToVol = new Dictionary<Camera, VolumetricRendering>(); } bool hasCam = SceneToVol.TryGetValue(sceneCam, out vol); if (!hasCam) { GameObject sceneVol = new GameObject(); sceneVol.hideFlags = HideFlags.DontSave; sceneVol.transform.parent = this.transform; sceneVol.name = "Scene Camera Volume " + SceneToVol.Count; vol = sceneVol.AddComponent<VolumetricRendering>(); VolumetricRendering mainVol = Camera.main?.GetComponent<VolumetricRendering>(); VolumetricData volData = mainVol?.volumetricData; if (mainVol == null || volData == null) { volData = AssetDatabase.LoadAssetAtPath<VolumetricData>("Packages/com.unity.render-pipelines.universal/Runtime/Volumetrics/PlaceholderVolumetricSettings.asset"); } if (mainVol != null) { vol.tempOffset = mainVol.tempOffset; vol.volumetricData = mainVol.volumetricData; vol.reprojectionAmount = mainVol.reprojectionAmount; vol.FroxelBlur = mainVol.FroxelBlur; vol.SliceDistributionUniformity = mainVol.SliceDistributionUniformity; vol.albedo = mainVol.albedo; vol.meanFreePath = mainVol.meanFreePath; vol.StaticLightMultiplier = mainVol.StaticLightMultiplier; } vol.volumetricData = volData; vol.cam = sceneCam; SceneToVol.Add(sceneCam, vol); } return vol; } else { Debug.Log("NULL CAMERA"); return null; } } } }