OldBlueWater/BlueWater/Assets/StylizedWater2/Editor/Underwater/UnderwaterRendererInspector.cs

298 lines
13 KiB
C#
Raw Normal View History

2023-12-14 14:58:32 +00:00
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
#if URP
using UnityEngine.Rendering.Universal;
#endif
namespace StylizedWater2.UnderwaterRendering
{
[CustomEditor(typeof(UnderwaterRenderer))]
public class UnderwaterRendererInspector : Editor
{
private UnderwaterRenderer renderer;
private SerializedProperty waterLevelSource;
private SerializedProperty waterLevel;
private SerializedProperty waterLevelTransform;
private SerializedProperty waterLevelPadding;
private SerializedProperty waterMaterial;
private SerializedProperty dynamicMaterial;
private SerializedProperty useVolumeBlending;
private SerializedProperty startDistance;
private SerializedProperty fogDensity;
private SerializedProperty heightFogDepth;
private SerializedProperty heightFogDensity;
private SerializedProperty heightFogBrightness;
private SerializedProperty fogBrightness;
private SerializedProperty subsurfaceStrength;
private SerializedProperty causticsStrength;
private SerializedProperty distortionStrength;
private SerializedProperty distortionFrequency;
private SerializedProperty distortionSpeed;
private SerializedProperty offset;
private SerializedProperty waterLineThickness;
private SerializedProperty enableBlur;
private SerializedProperty enableDistortion;
#if URP
private bool renderFeaturePresent;
private bool renderFeatureEnabled;
private UnderwaterRenderFeature renderFeature;
private Editor renderFeatureEditor;
#endif
private void OnEnable()
{
renderer = (UnderwaterRenderer)target;
waterLevelSource = serializedObject.FindProperty("waterLevelSource");
waterLevel = serializedObject.FindProperty("waterLevel");
waterLevelTransform = serializedObject.FindProperty("waterLevelTransform");
waterLevelPadding = serializedObject.FindProperty("waterLevelPadding");
waterMaterial = serializedObject.FindProperty("waterMaterial");
dynamicMaterial = serializedObject.FindProperty("dynamicMaterial");
useVolumeBlending = serializedObject.FindProperty("useVolumeBlending");
startDistance = serializedObject.FindProperty("startDistance");
fogDensity = serializedObject.FindProperty("fogDensity");
heightFogDepth = serializedObject.FindProperty("heightFogDepth");
heightFogDensity = serializedObject.FindProperty("heightFogDensity");
heightFogBrightness = serializedObject.FindProperty("heightFogBrightness");
fogBrightness = serializedObject.FindProperty("fogBrightness");
subsurfaceStrength = serializedObject.FindProperty("subsurfaceStrength");
causticsStrength = serializedObject.FindProperty("causticsStrength");
distortionStrength = serializedObject.FindProperty("distortionStrength");
distortionFrequency = serializedObject.FindProperty("distortionFrequency");
distortionSpeed = serializedObject.FindProperty("distortionSpeed");
offset = serializedObject.FindProperty("offset");
waterLineThickness = serializedObject.FindProperty("waterLineThickness");
enableBlur = serializedObject.FindProperty("enableBlur");
enableDistortion = serializedObject.FindProperty("enableDistortion");
#if URP
renderFeaturePresent = PipelineUtilities.RenderFeatureAdded<UnderwaterRenderFeature>();
renderFeatureEnabled = PipelineUtilities.IsRenderFeatureEnabled<UnderwaterRenderFeature>();
renderFeature = PipelineUtilities.GetRenderFeature<UnderwaterRenderFeature>() as UnderwaterRenderFeature;
#endif
}
public override void OnInspectorGUI()
{
EditorGUILayout.LabelField("Version " + UnderwaterRenderer.Version, EditorStyles.centeredGreyMiniLabel);
#if URP
DrawNotifications();
EditorGUI.BeginChangeCheck();
serializedObject.Update();
EditorGUILayout.LabelField("Material", EditorStyles.boldLabel);
using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.PropertyField(waterMaterial);
EditorGUI.BeginDisabledGroup(waterMaterial.objectReferenceValue == null);
if (GUILayout.Button("Edit", EditorStyles.miniButton, GUILayout.Width(50f)))
{
Selection.activeObject = waterMaterial.objectReferenceValue;
}
EditorGUI.EndDisabledGroup();
}
UI.DrawNotification(waterMaterial.objectReferenceValue == null, "The water material used by the water plane must be assigned", MessageType.Error);
UI.DrawNotification(renderer.waterMaterial && renderer.waterMaterial.GetInt("_Cull") != (int)CullMode.Off, "The water material is not double-sided", "Make it so", () =>
{
StylizedWaterEditor.DisableCullingForMaterial(renderer.waterMaterial);
}, MessageType.Error);
if (waterMaterial.objectReferenceValue != null)
{
EditorGUILayout.PropertyField(dynamicMaterial);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Water level", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(waterLevelSource, new GUIContent("Source", waterLevelSource.tooltip));
if (waterLevelSource.intValue == (int)UnderwaterRenderer.WaterLevelSource.FixedValue)
{
EditorGUILayout.PropertyField(waterLevel);
}
else
{
EditorGUILayout.PropertyField(waterLevelTransform);
}
EditorGUILayout.PropertyField(waterLevelPadding);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(useVolumeBlending);
if (EditorGUI.EndChangeCheck())
{
renderer.GetVolumeSettings();
}
if (!useVolumeBlending.boolValue)
{
EditorGUI.indentLevel++;
EditorGUILayout.LabelField("Fog (distance from camera)", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(startDistance);
EditorGUILayout.PropertyField(fogDensity);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Fog (distance from water)", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(heightFogDepth);
EditorGUILayout.PropertyField(heightFogDensity);
EditorGUILayout.PropertyField(heightFogBrightness);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Multipliers", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(fogBrightness);
EditorGUILayout.PropertyField(subsurfaceStrength);
EditorGUILayout.PropertyField(causticsStrength);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Distortion", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(distortionStrength);
EditorGUILayout.PropertyField(distortionFrequency);
EditorGUILayout.PropertyField(distortionSpeed);
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Lens", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(offset);
EditorGUILayout.PropertyField(waterLineThickness);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Effects", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(enableBlur);
EditorGUILayout.PropertyField(enableDistortion);
if (renderFeature)
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("Render feature settings", EditorStyles.boldLabel);
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
{
if (!renderFeatureEditor) renderFeatureEditor = Editor.CreateEditor(renderFeature);
SerializedObject serializedRendererFeaturesEditor = renderFeatureEditor.serializedObject;
serializedRendererFeaturesEditor.Update();
EditorGUI.BeginChangeCheck();
renderFeatureEditor.OnInspectorGUI();
if (EditorGUI.EndChangeCheck())
{
serializedRendererFeaturesEditor.ApplyModifiedProperties();
EditorUtility.SetDirty(renderFeature);
}
}
}
}
if (EditorGUI.EndChangeCheck())
{
renderer.UpdateProperties();
serializedObject.ApplyModifiedProperties();
}
UI.DrawFooter();
#else
EditorGUILayout.HelpBox("The Stylized Water 2 asset or the Universal Render Pipeline is not installed.", MessageType.Error);
#endif
}
private void DrawNotifications()
{
#if URP
UI.DrawNotification( !AssetInfo.MeetsMinimumVersion(UnderwaterRenderer.MinBaseVersion), "Version mismatch, requires Stylized Water 2 v" + UnderwaterRenderer.MinBaseVersion +".\n\nUpdate to avoid any issues or resolve (shader) errors", "Update", () => AssetInfo.OpenInPackageManager(), MessageType.Error);
UI.DrawNotification(UniversalRenderPipeline.asset == null, "The Universal Render Pipeline is not active", MessageType.Error);
#if !UNITY_2021_1_OR_NEWER //No MSAA on depth texture yet
UI.DrawNotification(UniversalRenderPipeline.asset && UniversalRenderPipeline.asset.msaaSampleCount > 1, "MSAA is enabled, this causes artifacts in the fog", "Disable",
() =>
{
UniversalRenderPipeline.asset.msaaSampleCount = 1;
EditorUtility.SetDirty(UniversalRenderPipeline.asset);
},
MessageType.Warning);
#endif
using (new EditorGUI.DisabledGroupScope(Application.isPlaying))
{
UI.DrawNotification(!renderFeaturePresent, "The underwater render feature hasn't be added to the default renderer", "Add", () =>
{
PipelineUtilities.AddRenderFeature<UnderwaterRenderFeature>();
renderFeaturePresent = true;
renderFeature = PipelineUtilities.GetRenderFeature<UnderwaterRenderFeature>() as UnderwaterRenderFeature;
}, MessageType.Error);
}
if(Application.isPlaying && !renderFeaturePresent) EditorGUILayout.HelpBox("Exit play mode to perform this action", MessageType.Warning);
UI.DrawNotification(renderFeaturePresent && !renderFeatureEnabled, "The underwater render feature is disabled", "Enable", () =>
{
PipelineUtilities.ToggleRenderFeature<UnderwaterRenderFeature>(true);
renderFeatureEnabled = true;
}, MessageType.Warning);
#endif
}
[MenuItem("GameObject/3D Object/Water/Underwater rendering", false, 2000)]
[MenuItem("Window/Stylized Water 2/Set up underwater rendering", false, 3000)]
private static void CreateUnderwaterRenderer()
{
#if UNITY_2023_1_OR_NEWER
UnderwaterRenderer r = FindFirstObjectByType<UnderwaterRenderer>();
#else
UnderwaterRenderer r = FindObjectOfType<UnderwaterRenderer>();
#endif
if (r)
{
EditorUtility.DisplayDialog("Stylized Water 2", "An Underwater Renderer instance already exists. Only one can be created", "OK");
return;
}
GameObject obj = new GameObject("Underwater Renderer", typeof(UnderwaterRenderer));
Undo.RegisterCreatedObjectUndo(obj, "Created Underwater Renderer");
r = obj.GetComponent<UnderwaterRenderer>();
if (Selection.activeGameObject) obj.transform.parent = Selection.activeGameObject.transform;
Selection.activeObject = obj;
}
}
}