using UnityEngine; using UnityEditor; using System.Collections.Generic; namespace ShinySSRR { [CustomEditor(typeof(Reflections))] public class ReflectionsEditor : Editor { SerializedProperty ignore, scope, layerMask, nameFilter, subMeshMask; SerializedProperty smoothness, perSubMeshSmoothness, subMeshSettings; SerializedProperty useMaterialSmoothness, materialSmoothnessMapPropertyName, materialSmoothnessIntensityPropertyName; SerializedProperty useMaterialNormalMap, materialNormalMapPropertyName; SerializedProperty fresnel, fuzzyness, contactHardening; SerializedProperty overrideGlobalSettings; SerializedProperty sampleCount, maxRayLength, thickness, binarySearchIterations, refineThickness, thicknessFine, decay, jitter; ShinySSRR shiny; private void OnEnable() { ignore = serializedObject.FindProperty("ignore"); scope = serializedObject.FindProperty("scope"); layerMask = serializedObject.FindProperty("layerMask"); nameFilter = serializedObject.FindProperty("nameFilter"); subMeshMask = serializedObject.FindProperty("subMeshMask"); smoothness = serializedObject.FindProperty("smoothness"); useMaterialSmoothness = serializedObject.FindProperty("useMaterialSmoothness"); materialSmoothnessMapPropertyName = serializedObject.FindProperty("materialSmoothnessMapPropertyName"); materialSmoothnessIntensityPropertyName = serializedObject.FindProperty("materialSmoothnessIntensityPropertyName"); perSubMeshSmoothness = serializedObject.FindProperty("perSubMeshSmoothness"); subMeshSettings = serializedObject.FindProperty("subMeshSettings"); useMaterialNormalMap = serializedObject.FindProperty("useMaterialNormalMap"); materialNormalMapPropertyName = serializedObject.FindProperty("materialNormalMapPropertyName"); fresnel = serializedObject.FindProperty("fresnel"); fuzzyness = serializedObject.FindProperty("fuzzyness"); contactHardening = serializedObject.FindProperty("contactHardening"); overrideGlobalSettings = serializedObject.FindProperty("overrideGlobalSettings"); sampleCount = serializedObject.FindProperty("sampleCount"); maxRayLength = serializedObject.FindProperty("maxRayLength"); binarySearchIterations = serializedObject.FindProperty("binarySearchIterations"); thickness = serializedObject.FindProperty("thickness"); refineThickness = serializedObject.FindProperty("refineThickness"); thicknessFine = serializedObject.FindProperty("thicknessFine"); decay = serializedObject.FindProperty("decay"); jitter = serializedObject.FindProperty("jitter"); } public override void OnInspectorGUI() { if (shiny == null) { shiny = FindObjectOfType(); } if (shiny == null) { EditorGUILayout.HelpBox("Shiny SSRR must be added to the camera!", MessageType.Error); EditorGUILayout.Separator(); GUI.enabled = false; } else { EditorGUILayout.BeginVertical(GUI.skin.box); if (GUILayout.Button("Show Global Settings")) { Selection.SetActiveObjectWithContext(shiny.gameObject, null); GUIUtility.ExitGUI(); } EditorGUILayout.EndVertical(); } bool isForwardPath = true; if (shiny.isDeferredActive) { EditorGUILayout.HelpBox("In deferred mode, material properties like smoothness and normal map plus global SSR settings are used.", MessageType.Warning); isForwardPath = false; GUI.enabled = false; } // ensure submesh array size matches materials count Reflections refl = (Reflections)target; if (refl.ssrRenderers != null && refl.ssrRenderers.Count == 1 && refl.ssrRenderers[0].originalMaterials != null) { List materials = refl.ssrRenderers[0].originalMaterials; if (refl.subMeshSettings == null) { refl.subMeshSettings = new SubMeshSettingsData[materials.Count]; } else if (refl.subMeshSettings.Length < materials.Count) { System.Array.Resize(ref refl.subMeshSettings, materials.Count); } } serializedObject.Update(); EditorGUILayout.PropertyField(ignore); if (!ignore.boolValue) { if (refl.renderers?.Count == 0) { if (scope.intValue == (int)Scope.OnlyThisObject) { EditorGUILayout.HelpBox("No renderers found on this gameobject. Switch to 'Include Children' or add this script to another object which contains a renderer.", MessageType.Warning); } else { EditorGUILayout.HelpBox("No renderers found under this gameobject.", MessageType.Warning); } } EditorGUILayout.PropertyField(scope); if (scope.intValue == (int)Scope.IncludeChildren) { EditorGUI.indentLevel++; EditorGUILayout.PropertyField(layerMask); EditorGUILayout.PropertyField(nameFilter); EditorGUILayout.PropertyField(subMeshMask); EditorGUI.indentLevel--; } EditorGUILayout.PropertyField(useMaterialSmoothness); GUI.enabled = !useMaterialSmoothness.boolValue; EditorGUILayout.PropertyField(perSubMeshSmoothness); if (perSubMeshSmoothness.boolValue) { EditorGUILayout.PropertyField(subMeshSettings, new GUIContent("Smoothness Values"), true); } else { EditorGUILayout.PropertyField(smoothness); } GUI.enabled = isForwardPath; EditorGUILayout.PropertyField(useMaterialNormalMap); if (useMaterialSmoothness.boolValue || perSubMeshSmoothness.boolValue || useMaterialNormalMap.boolValue) { EditorGUILayout.Separator(); EditorGUILayout.LabelField("Material Property Names", EditorStyles.miniBoldLabel); if (useMaterialSmoothness.boolValue || perSubMeshSmoothness.boolValue) { EditorGUILayout.PropertyField(materialSmoothnessMapPropertyName, new GUIContent("Smoothness Map", "The material property name for the smoothness map")); EditorGUILayout.PropertyField(materialSmoothnessIntensityPropertyName, new GUIContent("Smoothness Intensity", "The material property name for the smoothness intensity")); } if (useMaterialNormalMap.boolValue) { EditorGUILayout.PropertyField(materialNormalMapPropertyName, new GUIContent("NormalMap", "The material property name for the normal map")); } } EditorGUILayout.PropertyField(overrideGlobalSettings); if (overrideGlobalSettings.boolValue) { EditorGUI.indentLevel++; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Apply Quality Preset:", GUILayout.Width(EditorGUIUtility.labelWidth)); if (GUILayout.Button("Fast")) { ApplyRaytracingPreset(RaytracingPreset.Fast); } if (GUILayout.Button("Medium")) { ApplyRaytracingPreset(RaytracingPreset.Medium); } if (GUILayout.Button("High")) { ApplyRaytracingPreset(RaytracingPreset.High); } if (GUILayout.Button("Superb")) { ApplyRaytracingPreset(RaytracingPreset.Superb); } if (GUILayout.Button("Ultra")) { ApplyRaytracingPreset(RaytracingPreset.Ultra); } EditorGUILayout.EndHorizontal(); EditorGUILayout.PropertyField(sampleCount); EditorGUILayout.PropertyField(maxRayLength); EditorGUILayout.PropertyField(thickness); EditorGUILayout.PropertyField(binarySearchIterations); EditorGUILayout.PropertyField(refineThickness); if (refineThickness.boolValue) { EditorGUILayout.PropertyField(thicknessFine); } EditorGUILayout.PropertyField(jitter); EditorGUILayout.PropertyField(fresnel); EditorGUILayout.PropertyField(decay); EditorGUILayout.PropertyField(fuzzyness, new GUIContent("Fuzziness")); EditorGUILayout.PropertyField(contactHardening); EditorGUI.indentLevel--; } } serializedObject.ApplyModifiedProperties(); } void ApplyRaytracingPreset(RaytracingPreset preset) { Reflections ssr = (Reflections)target; ssr.ApplyRaytracingPreset(preset); EditorUtility.SetDirty(ssr); } } }