ECM2
This commit is contained in:
14
Assets/VolumetricLightBeam/Editor/SD/Editor_CommonSD.cs
Normal file
14
Assets/VolumetricLightBeam/Editor/SD/Editor_CommonSD.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
#if UNITY_EDITOR
|
||||
namespace VLB
|
||||
{
|
||||
public class Editor_CommonSD : Editor_Common
|
||||
{
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
RetrieveSerializedProperties("_");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // UNITY_EDITOR
|
||||
|
||||
11
Assets/VolumetricLightBeam/Editor/SD/Editor_CommonSD.cs.meta
Normal file
11
Assets/VolumetricLightBeam/Editor/SD/Editor_CommonSD.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de0354a8f662c4649a2aee6dbd130cd2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace VLB
|
||||
{
|
||||
public class Editor_DynamicOcclusionAbstractBase<T> : Editor_CommonSD where T : DynamicOcclusionAbstractBase
|
||||
{
|
||||
SerializedProperty updateRate = null;
|
||||
SerializedProperty waitXFrames = null;
|
||||
protected TargetList<T> m_Targets;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
m_Targets = new TargetList<T>(targets);
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (!Config.Instance.featureEnabledDynamicOcclusion)
|
||||
{
|
||||
EditorGUILayout.HelpBox(EditorStrings.DynOcclusion.HelpFeatureDisabled, MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
protected void DisplayCommonInspector()
|
||||
{
|
||||
if (FoldableHeader.Begin(this, EditorStrings.DynOcclusion.HeaderUpdateRate))
|
||||
{
|
||||
updateRate.CustomEnum<DynamicOcclusionUpdateRate>(EditorStrings.DynOcclusion.UpdateRate, EditorStrings.DynOcclusion.UpdateRateDescriptions);
|
||||
|
||||
if (m_Targets.HasAtLeastOneTargetWith((T comp) => { return comp.updateRate.HasFlag(DynamicOcclusionUpdateRate.EveryXFrames); }))
|
||||
{
|
||||
EditorGUILayout.PropertyField(waitXFrames, EditorStrings.DynOcclusion.WaitXFrames);
|
||||
}
|
||||
|
||||
EditorGUILayout.HelpBox(
|
||||
string.Format(EditorStrings.DynOcclusion.GetUpdateRateAdvice<T>(m_Targets[0].updateRate), m_Targets[0].waitXFrames),
|
||||
MessageType.Info);
|
||||
}
|
||||
|
||||
FoldableHeader.End();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0192ed587a87bfb41b9ec2ac3f6098e2
|
||||
timeCreated: 1580771203
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,55 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace VLB
|
||||
{
|
||||
[CustomEditor(typeof(DynamicOcclusionDepthBuffer))]
|
||||
[CanEditMultipleObjects]
|
||||
public class Editor_DynamicOcclusionDepthBuffer : Editor_DynamicOcclusionAbstractBase<DynamicOcclusionDepthBuffer>
|
||||
{
|
||||
SerializedProperty depthMapResolution = null;
|
||||
SerializedProperty layerMask = null;
|
||||
SerializedProperty useOcclusionCulling = null;
|
||||
SerializedProperty fadeDistanceToSurface = null;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (m_Targets.HasAtLeastOneTargetWith((DynamicOcclusionDepthBuffer comp) => { return comp.GetComponent<VolumetricLightBeamSD>().dimensions == Dimensions.Dim2D; }))
|
||||
{
|
||||
EditorGUILayout.HelpBox(EditorStrings.DynOcclusion.HelpDepthBufferAndBeam2D, MessageType.Warning);
|
||||
}
|
||||
|
||||
if (FoldableHeader.Begin(this, EditorStrings.DynOcclusion.HeaderCamera))
|
||||
{
|
||||
EditorGUILayout.PropertyField(layerMask, EditorStrings.DynOcclusion.LayerMask);
|
||||
|
||||
if(Config.Instance.geometryOverrideLayer == false)
|
||||
{
|
||||
EditorGUILayout.HelpBox(EditorStrings.DynOcclusion.HelpOverrideLayer, MessageType.Warning);
|
||||
}
|
||||
else if (m_Targets.HasAtLeastOneTargetWith((DynamicOcclusionDepthBuffer comp) => { return comp.HasLayerMaskIssues(); }))
|
||||
{
|
||||
EditorGUILayout.HelpBox(EditorStrings.DynOcclusion.HelpLayerMaskIssues, MessageType.Warning);
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(useOcclusionCulling, EditorStrings.DynOcclusion.DepthBufferOcclusionCulling);
|
||||
EditorGUILayout.PropertyField(depthMapResolution, EditorStrings.DynOcclusion.DepthBufferDepthMapResolution);
|
||||
}
|
||||
FoldableHeader.End();
|
||||
|
||||
if (FoldableHeader.Begin(this, EditorStrings.DynOcclusion.HeaderOccluderSurface))
|
||||
{
|
||||
EditorGUILayout.PropertyField(fadeDistanceToSurface, EditorStrings.DynOcclusion.FadeDistanceToSurface);
|
||||
}
|
||||
FoldableHeader.End();
|
||||
|
||||
DisplayCommonInspector();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd6cc47c61bc28e4fb4568a2e48d1c32
|
||||
timeCreated: 1578172705
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,111 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace VLB
|
||||
{
|
||||
[CustomEditor(typeof(DynamicOcclusionRaycasting))]
|
||||
[CanEditMultipleObjects]
|
||||
public class Editor_DynamicOcclusionRaycasting : Editor_DynamicOcclusionAbstractBase<DynamicOcclusionRaycasting>
|
||||
{
|
||||
SerializedProperty dimensions = null;
|
||||
SerializedProperty layerMask = null;
|
||||
SerializedProperty considerTriggers = null;
|
||||
SerializedProperty minOccluderArea = null;
|
||||
SerializedProperty planeAlignment = null;
|
||||
SerializedProperty maxSurfaceDot = null;
|
||||
SerializedProperty planeOffset = null;
|
||||
SerializedProperty fadeDistanceToSurface = null;
|
||||
SerializedProperty minSurfaceRatio = null;
|
||||
|
||||
public override bool RequiresConstantRepaint() { return Application.isPlaying || DynamicOcclusionRaycasting.editorRaycastAtEachFrame; }
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
DynamicOcclusionRaycasting.EditorLoadPrefs();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (FoldableHeader.Begin(this, EditorStrings.DynOcclusion.HeaderRaycasting))
|
||||
{
|
||||
dimensions.CustomEnum<Dimensions>(EditorStrings.DynOcclusion.Dimensions, EditorStrings.Common.DimensionsEnumDescriptions);
|
||||
EditorGUILayout.PropertyField(layerMask, EditorStrings.DynOcclusion.LayerMask);
|
||||
EditorGUILayout.PropertyField(considerTriggers, EditorStrings.DynOcclusion.ConsiderTriggers);
|
||||
|
||||
if (Physics2D.queriesHitTriggers == false)
|
||||
{
|
||||
if(m_Targets.HasAtLeastOneTargetWith((DynamicOcclusionRaycasting instance) => { return instance.dimensions == Dimensions.Dim2D && instance.considerTriggers; }))
|
||||
{
|
||||
EditorGUILayout.HelpBox(EditorStrings.DynOcclusion.ConsiderTriggersNoPossible, MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(minOccluderArea, EditorStrings.DynOcclusion.MinOccluderArea);
|
||||
}
|
||||
|
||||
FoldableHeader.End();
|
||||
|
||||
DisplayCommonInspector();
|
||||
|
||||
if (FoldableHeader.Begin(this, EditorStrings.DynOcclusion.HeaderOccluderSurface))
|
||||
{
|
||||
minSurfaceRatio.FloatSlider(
|
||||
EditorStrings.DynOcclusion.MinSurfaceRatio,
|
||||
Consts.DynOcclusion.RaycastingMinSurfaceRatioMin, Consts.DynOcclusion.RaycastingMinSurfaceRatioMax,
|
||||
(value) => value * 100f, // conversion value to slider
|
||||
(value) => value / 100f // conversion slider to value
|
||||
);
|
||||
|
||||
maxSurfaceDot.FloatSlider(
|
||||
EditorStrings.DynOcclusion.MaxSurfaceDot,
|
||||
Consts.DynOcclusion.RaycastingMaxSurfaceAngleMin, Consts.DynOcclusion.RaycastingMaxSurfaceAngleMax,
|
||||
(value) => Mathf.Acos(value) * Mathf.Rad2Deg, // conversion value to slider
|
||||
(value) => Mathf.Cos(value * Mathf.Deg2Rad) // conversion slider to value
|
||||
);
|
||||
}
|
||||
|
||||
FoldableHeader.End();
|
||||
|
||||
if (FoldableHeader.Begin(this, EditorStrings.DynOcclusion.HeaderClippingPlane))
|
||||
{
|
||||
EditorGUILayout.PropertyField(planeAlignment, EditorStrings.DynOcclusion.PlaneAlignment);
|
||||
EditorGUILayout.PropertyField(planeOffset, EditorStrings.DynOcclusion.PlaneOffset);
|
||||
EditorGUILayout.PropertyField(fadeDistanceToSurface, EditorStrings.DynOcclusion.FadeDistanceToSurface);
|
||||
}
|
||||
|
||||
FoldableHeader.End();
|
||||
|
||||
if (FoldableHeader.Begin(this, EditorStrings.DynOcclusion.HeaderEditorDebug))
|
||||
{
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
EditorExtensions.GlobalToggleButton(ref DynamicOcclusionRaycasting.editorShowDebugPlane, EditorStrings.DynOcclusion.EditorShowDebugPlane, EditorPrefsStrings.DynOcclusion.PrefShowDebugPlane);
|
||||
EditorExtensions.GlobalToggleButton(ref DynamicOcclusionRaycasting.editorRaycastAtEachFrame, EditorStrings.DynOcclusion.EditorRaycastAtEachFrame, EditorPrefsStrings.DynOcclusion.PrefRaycastingEditor);
|
||||
}
|
||||
|
||||
if (Application.isPlaying || DynamicOcclusionRaycasting.editorRaycastAtEachFrame)
|
||||
{
|
||||
if (!serializedObject.isEditingMultipleObjects)
|
||||
{
|
||||
var instance = (target as DynamicOcclusionRaycasting);
|
||||
Debug.Assert(instance);
|
||||
var hit = instance.editorCurrentHitResult;
|
||||
var lastFrameUpdate = instance.editorDebugData.lastFrameUpdate;
|
||||
|
||||
var occluderInfo = string.Format("Last update {0} frame(s) ago\n", Time.frameCount - lastFrameUpdate);
|
||||
occluderInfo += (hit.hasCollider) ? string.Format("Current occluder: '{0}'\nEstimated occluder area: {1} units²", hit.name, hit.bounds.GetMaxArea2D()) : "No occluder found";
|
||||
EditorGUILayout.HelpBox(occluderInfo, MessageType.Info);
|
||||
}
|
||||
}
|
||||
}
|
||||
FoldableHeader.End();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 296c1775a3a72104091469b9f856ae7b
|
||||
timeCreated: 1508778801
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,47 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace VLB
|
||||
{
|
||||
[CustomEditor(typeof(SkewingHandleSD))]
|
||||
public class Editor_SkewingHandleSD : Editor_CommonSD
|
||||
{
|
||||
SerializedProperty volumetricLightBeam = null;
|
||||
SerializedProperty shouldUpdateEachFrame = null;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
var thisTarget = target as SkewingHandleSD;
|
||||
if (thisTarget == null)
|
||||
return;
|
||||
|
||||
if(Config.Instance.featureEnabledMeshSkewing == false)
|
||||
EditorGUILayout.HelpBox(EditorStrings.SkewingHandle.HelpFeatureDisabled, MessageType.Warning);
|
||||
|
||||
EditorGUILayout.PropertyField(volumetricLightBeam, EditorStrings.SkewingHandle.Beam);
|
||||
EditorGUILayout.PropertyField(shouldUpdateEachFrame, EditorStrings.SkewingHandle.ShouldUpdateEachFrame);
|
||||
|
||||
if (thisTarget.volumetricLightBeam)
|
||||
{
|
||||
if(thisTarget.IsAttachedToSelf())
|
||||
{
|
||||
EditorGUILayout.HelpBox(EditorStrings.SkewingHandle.ErrorAttachedToSelf, MessageType.Error);
|
||||
}
|
||||
else if (!thisTarget.CanSetSkewingVector())
|
||||
{
|
||||
EditorGUILayout.HelpBox(EditorStrings.SkewingHandle.ErrorCannotSkew, MessageType.Error);
|
||||
}
|
||||
else if (thisTarget.shouldUpdateEachFrame && !thisTarget.CanUpdateEachFrame())
|
||||
{
|
||||
EditorGUILayout.HelpBox(EditorStrings.SkewingHandle.ErrorCannotUpdate, MessageType.Error);
|
||||
}
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f95e2188469d17a4081bb82c36e6e8de
|
||||
timeCreated: 1604927219
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,562 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
#pragma warning disable 0429, 0162 // Unreachable expression code detected (because of Noise3D.isSupported on mobile)
|
||||
|
||||
namespace VLB
|
||||
{
|
||||
[CustomEditor(typeof(VolumetricLightBeamSD))]
|
||||
[CanEditMultipleObjects]
|
||||
public class Editor_VolumetricLightBeamSD : Editor_VolumetricLightBeamAbstractBase
|
||||
{
|
||||
SerializedProperty trackChangesDuringPlaytime = null;
|
||||
SerializedProperty colorFromLight = null, colorMode = null, color = null, colorGradient = null;
|
||||
SerializedProperty intensityFromLight = null, intensityModeAdvanced = null, intensityInside = null, intensityOutside = null, intensityMultiplier = null;
|
||||
SerializedProperty blendingMode = null, shaderAccuracy = null;
|
||||
SerializedProperty fresnelPow = null, glareFrontal = null, glareBehind = null;
|
||||
SerializedProperty spotAngleFromLight = null, spotAngle = null, spotAngleMultiplier = null;
|
||||
SerializedProperty coneRadiusStart = null, geomMeshType = null, geomCustomSides = null, geomCustomSegments = null, geomCap = null;
|
||||
SerializedProperty fallOffEndFromLight = null, fallOffStart = null, fallOffEnd = null, fallOffEndMultiplier = null;
|
||||
SerializedProperty attenuationEquation = null, attenuationCustomBlending = null;
|
||||
SerializedProperty depthBlendDistance = null, cameraClippingDistance = null;
|
||||
SerializedProperty noiseMode = null, noiseIntensity = null, noiseScaleUseGlobal = null, noiseScaleLocal = null, noiseVelocityUseGlobal = null, noiseVelocityLocal = null;
|
||||
SerializedProperty fadeOutBegin = null, fadeOutEnd = null;
|
||||
SerializedProperty dimensions = null, sortingLayerID = null, sortingOrder = null;
|
||||
SerializedProperty skewingLocalForwardDirection = null, clippingPlaneTransform = null, tiltFactor = null;
|
||||
SerializedProperty hdrpExposureWeight = null;
|
||||
|
||||
TargetList<VolumetricLightBeamSD> m_Targets;
|
||||
string[] m_SortingLayerNames;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
RetrieveSerializedProperties("_");
|
||||
|
||||
m_SortingLayerNames = SortingLayer.layers.Select(l => l.name).ToArray();
|
||||
m_Targets = new TargetList<VolumetricLightBeamSD>(targets);
|
||||
}
|
||||
|
||||
static void PropertyThickness(SerializedProperty sp)
|
||||
{
|
||||
sp.FloatSlider(
|
||||
EditorStrings.Beam.SD.SideThickness,
|
||||
0, 1,
|
||||
(value) => Mathf.Clamp01(1 - (value / Consts.Beam.SD.FresnelPowMaxValue)), // conversion value to slider
|
||||
(value) => (1 - value) * Consts.Beam.SD.FresnelPowMaxValue // conversion slider to value
|
||||
);
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
Debug.Assert(m_Targets.Count > 0);
|
||||
|
||||
#if VLB_DEBUG
|
||||
if (m_Targets.Count == 1)
|
||||
{
|
||||
string msg = "";
|
||||
var geom = m_Targets[0].GetComponentInChildren<BeamGeometrySD>();
|
||||
if (geom == null)
|
||||
msg = "No BeamGeometry";
|
||||
else
|
||||
msg = string.Format("Material: {0} | ID: {1} / {2}"
|
||||
, geom._EDITOR_IsUsingCustomMaterial ? "CUSTOM" : "INSTANCED"
|
||||
, geom._EDITOR_InstancedMaterialID
|
||||
, MaterialManager.StaticPropertiesSD.staticPropertiesCount);
|
||||
EditorGUILayout.LabelField(msg);
|
||||
}
|
||||
#endif // VLB_DEBUG
|
||||
|
||||
VolumetricLightBeamSD.AttachedLightType lightType;
|
||||
bool hasLightSpot = m_Targets[0].GetLightSpotAttachedSlow(out lightType) != null;
|
||||
if (lightType == VolumetricLightBeamSD.AttachedLightType.OtherLight)
|
||||
{
|
||||
EditorGUILayout.HelpBox(EditorStrings.Beam.HelpNoSpotlight, MessageType.Warning);
|
||||
}
|
||||
|
||||
if (FoldableHeader.Begin(this, EditorStrings.Beam.HeaderBasic))
|
||||
{
|
||||
// Color
|
||||
using (ButtonToggleScope.FromLight(colorFromLight, hasLightSpot))
|
||||
{
|
||||
if (!hasLightSpot) EditorGUILayout.BeginHorizontal(); // mandatory to have the color picker on the same line (when the button "from light" is not here)
|
||||
{
|
||||
if (Config.Instance.featureEnabledColorGradient == FeatureEnabledColorGradient.Off)
|
||||
{
|
||||
EditorGUILayout.PropertyField(color, EditorStrings.Beam.ColorMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
using (new EditorExtensions.LabelWidth(65f))
|
||||
{
|
||||
EditorGUILayout.PropertyField(colorMode, EditorStrings.Beam.ColorMode);
|
||||
}
|
||||
|
||||
if (colorMode.enumValueIndex == (int)ColorMode.Gradient)
|
||||
EditorGUILayout.PropertyField(colorGradient, EditorStrings.Beam.ColorGradient);
|
||||
else
|
||||
EditorGUILayout.PropertyField(color, EditorStrings.Beam.ColorFlat);
|
||||
}
|
||||
}
|
||||
if (!hasLightSpot) EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
// Blending Mode
|
||||
EditorGUILayout.PropertyField(blendingMode, EditorStrings.Beam.BlendingMode);
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
// Intensity
|
||||
bool advancedModeEnabled = false;
|
||||
using (var lightDisabledGrp = ButtonToggleScope.FromLight(intensityFromLight, hasLightSpot))
|
||||
{
|
||||
bool advancedModeButton = !hasLightSpot || intensityFromLight.HasAtLeastOneValue(false);
|
||||
using (ButtonToggleScope.Advanced(intensityModeAdvanced, advancedModeButton))
|
||||
{
|
||||
advancedModeEnabled = intensityModeAdvanced.HasAtLeastOneValue(true);
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
if (m_Targets.HasAtLeastOneTargetWith((VolumetricLightBeamSD beam) => { return beam.useIntensityFromAttachedLightSpot; }))
|
||||
{
|
||||
using (new EditorExtensions.ShowMixedValue(intensityOutside))
|
||||
{
|
||||
// display grayed out Unity's light intensity
|
||||
EditorGUILayout.FloatField(EditorStrings.Beam.SD.IntensityGlobal, SpotLightHelper.GetIntensity(m_Targets[0].lightSpotAttached));
|
||||
}
|
||||
|
||||
lightDisabledGrp?.EndDisabledGroup(); // muliplier factor should be available
|
||||
DrawMultiplierProperty(intensityMultiplier, EditorStrings.Beam.IntensityMultiplier); // multiplier property
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(intensityOutside, advancedModeEnabled ? EditorStrings.Beam.SD.IntensityOutside : EditorStrings.Beam.SD.IntensityGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (advancedModeEnabled)
|
||||
EditorGUILayout.PropertyField(intensityInside, EditorStrings.Beam.SD.IntensityInside);
|
||||
else
|
||||
intensityInside.floatValue = intensityOutside.floatValue;
|
||||
|
||||
if(Config.Instance.isHDRPExposureWeightSupported)
|
||||
{
|
||||
EditorGUILayout.PropertyField(hdrpExposureWeight, EditorStrings.Beam.HDRPExposureWeight);
|
||||
}
|
||||
|
||||
PropertyThickness(fresnelPow);
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
EditorGUILayout.PropertyField(glareFrontal, EditorStrings.Beam.GlareFrontal);
|
||||
EditorGUILayout.PropertyField(glareBehind, EditorStrings.Beam.GlareBehind);
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
if (Config.Instance.featureEnabledShaderAccuracyHigh)
|
||||
{
|
||||
EditorGUILayout.PropertyField(shaderAccuracy, EditorStrings.Beam.ShaderAccuracy);
|
||||
EditorGUILayout.Separator();
|
||||
}
|
||||
|
||||
trackChangesDuringPlaytime.ToggleLeft(EditorStrings.Beam.TrackChanges);
|
||||
DrawAnimatorWarning();
|
||||
}
|
||||
FoldableHeader.End();
|
||||
|
||||
if (FoldableHeader.Begin(this, EditorStrings.Beam.HeaderShape))
|
||||
{
|
||||
// Fade End
|
||||
using (var lightDisabledGrp = ButtonToggleScope.FromLight(fallOffEndFromLight, hasLightSpot))
|
||||
{
|
||||
if (m_Targets.HasAtLeastOneTargetWith((VolumetricLightBeamSD beam) => { return beam.useFallOffEndFromAttachedLightSpot; }))
|
||||
{
|
||||
using (new EditorExtensions.ShowMixedValue(fallOffEnd))
|
||||
{
|
||||
// display grayed out Unity's light range
|
||||
EditorGUILayout.FloatField(EditorStrings.Beam.FallOffEnd, SpotLightHelper.GetFallOffEnd(m_Targets[0].lightSpotAttached));
|
||||
}
|
||||
|
||||
lightDisabledGrp?.EndDisabledGroup(); // muliplier factor should be available
|
||||
DrawMultiplierProperty(fallOffEndMultiplier, EditorStrings.Beam.FallOffEndMultiplier); // multiplier property
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(fallOffEnd, EditorStrings.Beam.FallOffEnd);
|
||||
}
|
||||
}
|
||||
|
||||
// Spot Angle
|
||||
using (var lightDisabledGrp = ButtonToggleScope.FromLight(spotAngleFromLight, hasLightSpot))
|
||||
{
|
||||
if (m_Targets.HasAtLeastOneTargetWith((VolumetricLightBeamSD beam) => { return beam.useSpotAngleFromAttachedLightSpot; }))
|
||||
{
|
||||
using (new EditorExtensions.ShowMixedValue(spotAngle))
|
||||
{
|
||||
// display grayed out Unity's light angle
|
||||
EditorGUILayout.FloatField(EditorStrings.Beam.SpotAngle, SpotLightHelper.GetSpotAngle(m_Targets[0].lightSpotAttached));
|
||||
}
|
||||
|
||||
lightDisabledGrp?.EndDisabledGroup(); // muliplier factor should be available
|
||||
DrawMultiplierProperty(spotAngleMultiplier, EditorStrings.Beam.SpotAngleMultiplier); // multiplier property
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.Slider(spotAngle, Consts.Beam.SpotAngleMin, Consts.Beam.SpotAngleMax, EditorStrings.Beam.SpotAngle);
|
||||
}
|
||||
}
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
EditorGUILayout.PropertyField(coneRadiusStart, EditorStrings.Beam.ConeRadiusStart);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
{
|
||||
geomCap.ToggleLeft(EditorStrings.Beam.GeomCap, GUILayout.MaxWidth(42.0f));
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck()) { SetMeshesDirty(); }
|
||||
}
|
||||
}
|
||||
FoldableHeader.End();
|
||||
|
||||
if (FoldableHeader.Begin(this, EditorStrings.Beam.HeaderAttenuation))
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.PropertyField(attenuationEquation, EditorStrings.Beam.SD.AttenuationEquation);
|
||||
if (attenuationEquation.enumValueIndex == (int)AttenuationEquation.Blend)
|
||||
EditorGUILayout.PropertyField(attenuationCustomBlending, EditorStrings.Beam.SD.AttenuationCustomBlending);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (fallOffEnd.hasMultipleDifferentValues)
|
||||
EditorGUILayout.PropertyField(fallOffStart, EditorStrings.Beam.FallOffStart);
|
||||
else
|
||||
fallOffStart.FloatSlider(EditorStrings.Beam.FallOffStart, 0f, fallOffEnd.floatValue - Consts.Beam.FallOffDistancesMinThreshold);
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
// Tilt
|
||||
if (m_Targets.HasAtLeastOneTargetWith((VolumetricLightBeamSD beam) => { return beam.shaderAccuracy == ShaderAccuracy.High; }))
|
||||
{
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
EditorGUILayout.PropertyField(tiltFactor, EditorStrings.Beam.SD.TiltFactor);
|
||||
EditorExtensions.GlobalToggleButton(ref VolumetricLightBeamSD.editorShowTiltFactor, EditorStrings.Beam.SD.EditorShowTiltDirection, EditorPrefsStrings.Beam.PrefShowTiltDir, 50f);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Targets.HasAtLeastOneTargetWith((VolumetricLightBeamSD beam) => { return beam.isTilted && beam.shaderAccuracy != ShaderAccuracy.High; }))
|
||||
EditorGUILayout.HelpBox(EditorStrings.Beam.SD.HelpTiltedWithShaderAccuracyFast, MessageType.Warning);
|
||||
}
|
||||
FoldableHeader.End();
|
||||
|
||||
if (Config.Instance.featureEnabledNoise3D)
|
||||
{
|
||||
if (FoldableHeader.Begin(this, EditorStrings.Beam.Header3DNoise))
|
||||
{
|
||||
noiseMode.CustomEnum<NoiseMode>(EditorStrings.Beam.NoiseMode, EditorStrings.Beam.NoiseModeEnumDescriptions);
|
||||
|
||||
bool showNoiseProps = m_Targets.HasAtLeastOneTargetWith((VolumetricLightBeamSD beam) => { return beam.isNoiseEnabled; });
|
||||
if (showNoiseProps)
|
||||
{
|
||||
EditorGUILayout.PropertyField(noiseIntensity, EditorStrings.Beam.NoiseIntensity);
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
using (new EditorGUI.DisabledGroupScope(noiseScaleUseGlobal.boolValue))
|
||||
{
|
||||
EditorGUILayout.PropertyField(noiseScaleLocal, EditorStrings.Beam.NoiseScale);
|
||||
}
|
||||
noiseScaleUseGlobal.ToggleUseGlobalNoise();
|
||||
}
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
using (new EditorGUI.DisabledGroupScope(noiseVelocityUseGlobal.boolValue))
|
||||
{
|
||||
EditorGUILayout.PropertyField(noiseVelocityLocal, EditorStrings.Beam.NoiseVelocity);
|
||||
}
|
||||
noiseVelocityUseGlobal.ToggleUseGlobalNoise();
|
||||
}
|
||||
|
||||
if (Noise3D.isSupported && !Noise3D.isProperlyLoaded)
|
||||
EditorGUILayout.HelpBox(EditorStrings.Common.HelpNoiseLoadingFailed, MessageType.Error);
|
||||
|
||||
if (!Noise3D.isSupported)
|
||||
EditorGUILayout.HelpBox(Noise3D.isNotSupportedString, MessageType.Info);
|
||||
}
|
||||
}
|
||||
FoldableHeader.End();
|
||||
}
|
||||
|
||||
if(FoldableHeader.Begin(this, EditorStrings.Beam.HeaderBlendingDistances))
|
||||
{
|
||||
{
|
||||
var content = AddEnabledStatusToContentText(EditorStrings.Beam.CameraClippingDistance, cameraClippingDistance);
|
||||
EditorGUILayout.PropertyField(cameraClippingDistance, content);
|
||||
}
|
||||
|
||||
{
|
||||
var content = AddEnabledStatusToContentText(EditorStrings.Beam.DepthBlendDistance, depthBlendDistance);
|
||||
EditorGUILayout.PropertyField(depthBlendDistance, content);
|
||||
}
|
||||
}
|
||||
FoldableHeader.End();
|
||||
|
||||
if(FoldableHeader.Begin(this, EditorStrings.Beam.HeaderGeometry))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
{
|
||||
EditorGUILayout.PropertyField(geomMeshType, EditorStrings.Beam.GeomMeshType);
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck()) { SetMeshesDirty(); }
|
||||
|
||||
if (geomMeshType.intValue == (int)MeshType.Custom)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
{
|
||||
EditorGUILayout.PropertyField(geomCustomSides, EditorStrings.Beam.GeomSides);
|
||||
EditorGUILayout.PropertyField(geomCustomSegments, EditorStrings.Beam.GeomSegments);
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck()) { SetMeshesDirty(); }
|
||||
|
||||
if (Config.Instance.featureEnabledMeshSkewing)
|
||||
{
|
||||
var vec3 = skewingLocalForwardDirection.vector3Value;
|
||||
var vec2 = Vector2.zero;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
{
|
||||
vec2 = EditorGUILayout.Vector2Field(EditorStrings.Beam.SD.SkewingLocalForwardDirection, vec3.xy());
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
vec3 = new Vector3(vec2.x, vec2.y, 1.0f);
|
||||
skewingLocalForwardDirection.vector3Value = vec3;
|
||||
SetMeshesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Targets.Count == 1)
|
||||
{
|
||||
EditorGUILayout.HelpBox(m_Targets[0].meshStats, MessageType.Info);
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
EditorGUILayout.PropertyField(clippingPlaneTransform, EditorStrings.Beam.SD.ClippingPlane);
|
||||
|
||||
if (m_Targets.HasAtLeastOneTargetWith((VolumetricLightBeamSD beam) => { return beam.clippingPlaneTransform != null; }))
|
||||
{
|
||||
EditorExtensions.GlobalToggleButton(ref VolumetricLightBeamSD.editorShowClippingPlane, EditorStrings.Beam.SD.EditorShowClippingPlane, EditorStrings.Beam.SD.PrefShowAddClippingPlane, 50f);
|
||||
}
|
||||
}
|
||||
}
|
||||
FoldableHeader.End();
|
||||
|
||||
if (FoldableHeader.Begin(this, EditorStrings.Beam.HeaderFadeOut))
|
||||
{
|
||||
bool wasEnabled = fadeOutBegin.floatValue <= fadeOutEnd.floatValue;
|
||||
|
||||
if(m_Targets.HasAtLeastOneTargetWith((VolumetricLightBeamSD beam) => { return (beam.fadeOutBegin <= beam.fadeOutEnd) != wasEnabled; }))
|
||||
{
|
||||
wasEnabled = true;
|
||||
EditorGUI.showMixedValue = true;
|
||||
}
|
||||
|
||||
System.Action<float> setFadeOutBegin = value =>
|
||||
{
|
||||
fadeOutBegin.floatValue = value;
|
||||
m_Targets.RecordUndoAction("Change Fade Out Begin Distance",
|
||||
(VolumetricLightBeamSD beam) => { beam.fadeOutBegin = value; });
|
||||
};
|
||||
|
||||
System.Action<float> setFadeOutEnd = value =>
|
||||
{
|
||||
fadeOutEnd.floatValue = value;
|
||||
m_Targets.RecordUndoAction("Change Fade Out End Distance",
|
||||
(VolumetricLightBeamSD beam) => { beam.fadeOutEnd = value; });
|
||||
};
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
bool isEnabled = EditorGUILayout.Toggle(EditorStrings.Beam.FadeOutEnabled, wasEnabled);
|
||||
EditorGUI.showMixedValue = false;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
float invValue = isEnabled ? 1 : -1;
|
||||
float valueA = Mathf.Abs(fadeOutBegin.floatValue);
|
||||
float valueB = Mathf.Abs(fadeOutEnd.floatValue);
|
||||
setFadeOutBegin(invValue * Mathf.Min(valueA, valueB));
|
||||
setFadeOutEnd (invValue * Mathf.Max(valueA, valueB));
|
||||
}
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
const float kEpsilon = 0.1f;
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(fadeOutBegin, EditorStrings.Beam.FadeOutBegin);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
setFadeOutBegin(Mathf.Clamp(fadeOutBegin.floatValue, 0, fadeOutEnd.floatValue - kEpsilon));
|
||||
}
|
||||
|
||||
using (new EditorExtensions.LabelWidth(30f))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(fadeOutEnd, EditorStrings.Beam.FadeOutEnd);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
setFadeOutEnd(Mathf.Max(fadeOutBegin.floatValue + kEpsilon, fadeOutEnd.floatValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
if(Config.Instance.fadeOutCameraTransform == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox(EditorStrings.Beam.HelpFadeOutNoMainCamera, MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FoldableHeader.End();
|
||||
|
||||
if (FoldableHeader.Begin(this, EditorStrings.Beam.Header2D))
|
||||
{
|
||||
dimensions.CustomEnum<Dimensions>(EditorStrings.Beam.Dimensions, EditorStrings.Common.DimensionsEnumDescriptions);
|
||||
DrawSortingLayerAndOrder();
|
||||
}
|
||||
FoldableHeader.End();
|
||||
|
||||
DrawInfos();
|
||||
DrawEditInSceneButton();
|
||||
DrawCustomActionButtons();
|
||||
DrawAdditionalFeatures();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
GUIContent AddEnabledStatusToContentText(GUIContent inContent, SerializedProperty prop)
|
||||
{
|
||||
Debug.Assert(prop.propertyType == SerializedPropertyType.Float);
|
||||
|
||||
var content = new GUIContent(inContent);
|
||||
if (prop.hasMultipleDifferentValues)
|
||||
content.text += " (-)";
|
||||
else
|
||||
content.text += prop.floatValue > 0.0 ? " (on)" : " (off)";
|
||||
return content;
|
||||
}
|
||||
|
||||
void SetMeshesDirty()
|
||||
{
|
||||
foreach (var entity in m_Targets) entity._EditorSetMeshDirty();
|
||||
}
|
||||
|
||||
void DrawSortingLayerAndOrder()
|
||||
{
|
||||
var updatedProperties = SortingLayerAndOrderDrawer.Draw(sortingLayerID, sortingOrder);
|
||||
|
||||
if(updatedProperties.HasFlag(SortingLayerAndOrderDrawer.UpdatedProperties.SortingLayerID))
|
||||
m_Targets.RecordUndoAction("Edit Sorting Layer", (VolumetricLightBeamSD beam) => beam.sortingLayerID = sortingLayerID.intValue); // call setters
|
||||
|
||||
if (updatedProperties.HasFlag(SortingLayerAndOrderDrawer.UpdatedProperties.SortingOrder))
|
||||
m_Targets.RecordUndoAction("Edit Sorting Order", (VolumetricLightBeamSD beam) => beam.sortingOrder = sortingOrder.intValue); // call setters
|
||||
}
|
||||
|
||||
void DrawAnimatorWarning()
|
||||
{
|
||||
var showAnimatorWarning = m_Targets.HasAtLeastOneTargetWith((VolumetricLightBeamSD beam) => { return beam.GetComponent<Animator>() != null && beam.trackChangesDuringPlaytime == false; });
|
||||
|
||||
if (showAnimatorWarning)
|
||||
EditorGUILayout.HelpBox(EditorStrings.Beam.SD.HelpAnimatorWarning, MessageType.Warning);
|
||||
}
|
||||
|
||||
void DrawCustomActionButtons()
|
||||
{
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
if (GUILayout.Button(EditorStrings.Beam.ButtonResetProperties, EditorStyles.miniButton))
|
||||
{
|
||||
m_Targets.RecordUndoAction("Reset Light Beam Properties",
|
||||
(VolumetricLightBeamSD beam) => { beam.Reset(); beam.GenerateGeometry(); } );
|
||||
}
|
||||
|
||||
if(m_Targets.HasAtLeastOneTargetWith((VolumetricLightBeamSD beam) => { return beam.geomMeshType == MeshType.Custom; }))
|
||||
{
|
||||
if (GUILayout.Button(EditorStrings.Beam.ButtonGenerateGeometry, EditorStyles.miniButton))
|
||||
{
|
||||
foreach (var entity in m_Targets) entity.GenerateGeometry();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawAdditionalFeatures()
|
||||
{
|
||||
if (Application.isPlaying) return; // do not support adding additional components at runtime
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
DrawButtonAddComponentDust();
|
||||
|
||||
bool showButtonOcclusion = Config.Instance.featureEnabledDynamicOcclusion && m_Targets.HasAtLeastOneTargetWith((VolumetricLightBeamSD beam) => { return beam.GetComponent<DynamicOcclusionAbstractBase>() == null; });
|
||||
if (showButtonOcclusion && GUILayout.Button(EditorData.Instance.contentAddDynamicOcclusion, buttonAddComponentStyle))
|
||||
{
|
||||
var menu = new GenericMenu();
|
||||
menu.AddItem(new GUIContent(EditorStrings.Beam.ButtonAddDynamicOcclusionRaycasting), false, AddComponentToTargets<DynamicOcclusionRaycasting>);
|
||||
menu.AddItem(new GUIContent(EditorStrings.Beam.ButtonAddDynamicOcclusionDepthBuffer), false, AddComponentToTargets<DynamicOcclusionDepthBuffer>);
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
DrawButtonAddComponentEffect();
|
||||
DrawButtonAddComponentTriggerZone();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void GetInfoTips(List<InfoTip> tips)
|
||||
{
|
||||
if (m_Targets.Count == 1)
|
||||
{
|
||||
if (depthBlendDistance.floatValue > 0f || !Noise3D.isSupported || trackChangesDuringPlaytime.boolValue)
|
||||
{
|
||||
if (depthBlendDistance.floatValue > 0f)
|
||||
{
|
||||
#if UNITY_IPHONE || UNITY_IOS || UNITY_ANDROID
|
||||
tips.Add(new InfoTip { type = MessageType.Info, message = EditorStrings.Beam.SD.HelpDepthMobile });
|
||||
#endif
|
||||
}
|
||||
|
||||
if (trackChangesDuringPlaytime.boolValue)
|
||||
tips.Add(new InfoTip { type = MessageType.Info, message = EditorStrings.Beam.SD.HelpTrackChangesEnabled });
|
||||
}
|
||||
}
|
||||
|
||||
base.GetInfoTips(tips);
|
||||
}
|
||||
|
||||
protected virtual void OnSceneGUI()
|
||||
{
|
||||
if(DrawEditInSceneHandles())
|
||||
{
|
||||
var beam = target as VolumetricLightBeamSD;
|
||||
Debug.Assert(beam != null);
|
||||
beam.UpdateAfterManualPropertyChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bd45af80c148e249bd23ff7970f6181
|
||||
timeCreated: 1504689328
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user