还原水插件
This commit is contained in:
@@ -66,16 +66,12 @@ namespace WaveHarmonic.Crest.Editor
|
||||
message += $"Scale: {target.CalcLodScale(i)}\n";
|
||||
message += $"Texel: {2f * 2f * target.CalcLodScale(i) / target.LodResolution}\n";
|
||||
message += $"Minimum Slice: {Mathf.Floor(Mathf.Log(Mathf.Max(i / baseTexelSize, 1f), 2f))}";
|
||||
message += "\n\n";
|
||||
if (i < target.LodLevels - 1) message += "\n\n";
|
||||
}
|
||||
|
||||
message += $"Scale: {target.Scale}\n";
|
||||
|
||||
message += "\n";
|
||||
|
||||
if (target.Surface.Material.HasVector(WaterRenderer.ShaderIDs.s_Absorption))
|
||||
{
|
||||
message += $"Depth Fog Density: {target.Surface.Material.GetVector(WaterRenderer.ShaderIDs.s_Absorption)}";
|
||||
message += $"\n\nDepth Fog Density: {target.Surface.Material.GetVector(WaterRenderer.ShaderIDs.s_Absorption)}";
|
||||
}
|
||||
|
||||
EditorGUILayout.HelpBox(message, MessageType.None);
|
||||
|
||||
@@ -71,15 +71,11 @@ namespace WaveHarmonic.Crest.Editor
|
||||
{ "_Crest_NormalMapStrength", "Strength of normal map influence" },
|
||||
{ "_Crest_NormalMapScale", "Base scale of multi-scale normal map texture" },
|
||||
{ "_Crest_NormalMapScrollSpeed", "Speed of the normal maps scrolling" },
|
||||
{ "_Crest_NormalMapTurbulenceEnabled", "Increase chance of sparkles where water is turbulent" },
|
||||
{ "_Crest_NormalMapTurbulenceStrength", "Strength of the normal map influence where turbulent" },
|
||||
{ "_Crest_NormalMapTurbulenceCoverage", "The threshold where turbulence triggers this effect.\n\nValues above 0.9 may be too high for calmer wave conditions, as it will trigger the effect where water is not turbulent. Furthermore, a value of one or very close one can cause a pop when weighing out waves to zero" },
|
||||
{ "_Crest_AbsorptionColor", "Works as a color (ie red adds red rather than subtracts red). This value is converted to real absorption values (proportion of light getting absorbed by water in atoms per meter). Alpha channel is for density. High alpha and darker color reduces transparency" },
|
||||
{ "_Crest_Scattering", "Light scattered by the water towards the viewer (in-scattered) per meter. Brighter color reduces transparency" },
|
||||
{ "_Crest_Anisotropy", "The directionality of the scattering where zero means scattered in all directions. The further towards one, the less visible soft shadows will be" },
|
||||
{ "_Crest_DirectTerm", "Scale direct light contribution to volume lighting" },
|
||||
{ "_Crest_AmbientTerm", "Scale ambient light contribution to volume lighting" },
|
||||
{ "_Crest_ShadowsAffectsAmbientFactor", "How much shadows affect ambient lighting. Typically this not required, but can help scenes with large shadowed areas" },
|
||||
{ "_Crest_SSSEnabled", "Whether to to emulate light scattering through waves" },
|
||||
{ "_Crest_SSSIntensity", "Direct light contribution intensity. Applied to the scattering color. This effect is best if subtle" },
|
||||
{ "_Crest_SSSPinchMinimum", "Higher the value the more scattering is towards the peaks of the waves" },
|
||||
@@ -97,7 +93,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
{ "_Crest_PlanarReflectionsEnabled", "Dynamically rendered 'reflection plane' style reflections. Requires Reflections to be enabled on the Water Renderer" },
|
||||
{ "_Crest_PlanarReflectionsIntensity", "Intensity of the planar reflections" },
|
||||
{ "_Crest_PlanarReflectionsDistortion", "How much the water normal affects the planar reflection" },
|
||||
{ "_Crest_PlanarReflectionsApplySmoothness", "Whether to apply smoothness to planar reflection sample via mip-map blending. Enabling will likely incur artifacts with most perturbed water" },
|
||||
{ "_Crest_PlanarReflectionsRoughness", "Controls the mipmap range" },
|
||||
{ "_Crest_RefractionStrength", "How strongly light is refracted when passing through water surface" },
|
||||
{ "_Crest_RefractiveIndexOfWater", "Index of refraction of water - typically left at 1.333. Changing this value can increase/decrease the size of the Snell's window" },
|
||||
@@ -112,16 +107,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
{ "_Crest_FoamIntensityAlbedo", "Scale intensity of diffuse lighting" },
|
||||
{ "_Crest_FoamSmoothness", "Smoothness of foam material" },
|
||||
{ "_Crest_FoamNormalStrength", "Strength of the generated normals" },
|
||||
{ "_Crest_FoamBioluminescenceEnabled", "Enables a foam-based bioluminescence. This reuses the foam sample" },
|
||||
{ "_Crest_FoamBioluminescenceColor", "The color and intensity of the bioluminescence" },
|
||||
{ "_Crest_FoamBioluminescenceIntensity", "The intensity of the bioluminescent foam" },
|
||||
{ "_Crest_FoamBioluminescenceMaximumDepth", "The maximum water depth where bioluminescence can appear. This can be used to keep bioluminescence localized to the shoreline" },
|
||||
{ "_Crest_FoamBioluminescenceSeaLevelOnly", "Only render foam bioluminescence at sea level. This will fade bioluminescence to be fully gone at 1m from sea level." },
|
||||
{ "_Crest_FoamBioluminescenceGlowIntensity", "The intensity of the bioluminescent glow" },
|
||||
{ "_Crest_FoamBioluminescenceGlowCoverage", "The coverage of the bioluminescent glow. Glow is based on raw foam data which makes it more present than foam" },
|
||||
{ "_Crest_FoamBioluminescenceSparklesEnabled", "Whether to apply bioluminescent sparkles. This uses the green channel of the foam texture as an emissive map" },
|
||||
{ "_Crest_FoamBioluminescenceSparklesIntensity", "The intensity of the bioluminescent sparkles" },
|
||||
{ "_Crest_FoamBioluminescenceSparklesCoverage", "The coverage of the bioluminescent sparkles. Sparkles placement is based on raw foam data which makes it more present than foam" },
|
||||
{ "_Crest_CausticsEnabled", "Approximate rays being focused/defocused on underwater surfaces" },
|
||||
{ "_Crest_CausticsTexture", "Caustics texture" },
|
||||
{ "_Crest_CausticsStrength", "Intensity of caustics effect" },
|
||||
@@ -130,15 +115,13 @@ namespace WaveHarmonic.Crest.Editor
|
||||
{ "_Crest_CausticsTextureAverage", "The 'mid' value of the caustics texture, around which the caustic texture values are scaled. Decreasing this value will reduce the caustics darkening underwater surfaces" },
|
||||
{ "_Crest_CausticsFocalDepth", "The depth at which the caustics are in focus" },
|
||||
{ "_Crest_CausticsDepthOfField", "The range of depths over which the caustics are in focus" },
|
||||
{ "_Crest_CausticsForceDistortion", "Forces the distortion texture to be applied for above water. This can be used to distort caustics even when there is no waves" },
|
||||
{ "_Crest_CausticsDistortionTexture", "Texture to distort caustics. Only applicable to underwater effect for now" },
|
||||
{ "_Crest_CausticsDistortionStrength", "How much the caustics texture is distorted" },
|
||||
{ "_Crest_CausticsDistortionScale", "The scale of the distortion pattern used to distort the caustics" },
|
||||
{ "_Crest_CausticsMotionBlur", "How much caustics are blurred when advected by flow" },
|
||||
{ "_CREST_FLOW_LOD", "Flow is horizontal motion of water. Flow must be enabled on the Water Renderer to generate flow data" },
|
||||
{ "CREST_FLOW", "Flow is horizontal motion of water. Flow must be enabled on the Water Renderer to generate flow data" },
|
||||
{ "_Crest_AlbedoEnabled", "Enable the Albedo simulation layer. Albedo must be enabled on the Water" },
|
||||
{ "_Crest_AlbedoIgnoreFoam", "Whether Albedo renders over the top of foam or not." },
|
||||
{ "_Crest_TransparencyMinimumAlpha", "The minimum alpha value for transparency. Makes water contribution to the final image stronger instead of the scene behind it" },
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using WaveHarmonic.Crest.Editor.Settings;
|
||||
|
||||
namespace WaveHarmonic.Crest.Editor
|
||||
{
|
||||
static partial class MaterialUpgrader
|
||||
{
|
||||
[InitializeOnLoadMethod]
|
||||
static void OnLoad()
|
||||
{
|
||||
EditorApplication.update += OnEditorUpdate;
|
||||
}
|
||||
|
||||
static void OnEditorUpdate()
|
||||
{
|
||||
if (Time.renderedFrameCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (EditorApplication.isUpdating)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ProjectSettings.Instance._MaterialVersion > 0)
|
||||
{
|
||||
EditorApplication.update -= OnEditorUpdate;
|
||||
return;
|
||||
}
|
||||
|
||||
UpgradeMaterials(force: false);
|
||||
|
||||
EditorApplication.update -= OnEditorUpdate;
|
||||
}
|
||||
|
||||
[MenuItem("Edit/Crest/Materials/Upgrade Materials")]
|
||||
static void OnMenuSelect()
|
||||
{
|
||||
UpgradeMaterials(force: true);
|
||||
}
|
||||
|
||||
static void UpgradeMaterials(bool force)
|
||||
{
|
||||
var dirty = false;
|
||||
var version = force ? 0 : ProjectSettings.Instance._MaterialVersion;
|
||||
|
||||
AssetDatabase.StartAssetEditing();
|
||||
try
|
||||
{
|
||||
foreach (var guid in AssetDatabase.FindAssets("t:Material"))
|
||||
{
|
||||
var material = AssetDatabase.LoadAssetAtPath<Material>(AssetDatabase.GUIDToAssetPath(guid));
|
||||
dirty |= UpgradeMaterial(material, version);
|
||||
}
|
||||
|
||||
ProjectSettings.Instance._MaterialVersion = k_MaterialVersion;
|
||||
ProjectSettings.Save();
|
||||
|
||||
if (dirty)
|
||||
{
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
AssetDatabase.StopAssetEditing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static partial class MaterialUpgrader
|
||||
{
|
||||
enum SerializedType
|
||||
{
|
||||
Boolean,
|
||||
Integer,
|
||||
Float,
|
||||
Vector,
|
||||
Color,
|
||||
Texture,
|
||||
Keyword,
|
||||
}
|
||||
|
||||
static bool TryFindBase(SerializedObject material, SerializedType type, out SerializedProperty propertyBase)
|
||||
{
|
||||
propertyBase = material.FindProperty("m_SavedProperties");
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SerializedType.Integer:
|
||||
propertyBase = propertyBase.FindPropertyRelative("m_Ints");
|
||||
return true;
|
||||
case SerializedType.Boolean:
|
||||
case SerializedType.Float:
|
||||
propertyBase = propertyBase.FindPropertyRelative("m_Floats");
|
||||
return true;
|
||||
case SerializedType.Color:
|
||||
case SerializedType.Vector:
|
||||
propertyBase = propertyBase.FindPropertyRelative("m_Colors");
|
||||
return true;
|
||||
case SerializedType.Texture:
|
||||
propertyBase = propertyBase.FindPropertyRelative("m_TexEnvs");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static SerializedProperty FindBase(SerializedObject material, SerializedType type)
|
||||
{
|
||||
if (!TryFindBase(material, type, out var root))
|
||||
{
|
||||
throw new System.ArgumentException($"Unknown SerializedType {type}");
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
static bool TryFindProperty(SerializedObject material, string name, SerializedType type, out SerializedProperty property, out int index, SerializedProperty root)
|
||||
{
|
||||
var isKeyword = type == SerializedType.Keyword;
|
||||
|
||||
property = null;
|
||||
var size = root.arraySize;
|
||||
for (index = 0; index < size; ++index)
|
||||
{
|
||||
property = root.GetArrayElementAtIndex(index);
|
||||
if (isKeyword ? property.stringValue == name : property.FindPropertyRelative("first").stringValue == name)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isKeyword)
|
||||
{
|
||||
property = property.FindPropertyRelative("second");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TryFindProperty(SerializedObject material, string name, SerializedType type, out SerializedProperty property, out int index, out SerializedProperty root)
|
||||
{
|
||||
if (type == SerializedType.Keyword)
|
||||
{
|
||||
root = material.FindProperty("m_ValidKeywords");
|
||||
if (TryFindProperty(material, name, type, out property, out index, root))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
root = material.FindProperty("m_InvalidKeywords");
|
||||
if (TryFindProperty(material, name, type, out property, out index, root))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
root = FindBase(material, type);
|
||||
return TryFindProperty(material, name, type, out property, out index, root);
|
||||
}
|
||||
|
||||
static bool RenameFloat(SerializedObject so, Material material, string old, string @new)
|
||||
{
|
||||
if (!TryFindProperty(so, old, SerializedType.Float, out var oldProperty, out var oldIndex, out var parent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var oldValue = oldProperty.floatValue;
|
||||
parent.DeleteArrayElementAtIndex(oldIndex);
|
||||
parent.InsertArrayElementAtIndex(0);
|
||||
var newProperty = parent.GetArrayElementAtIndex(0);
|
||||
newProperty.FindPropertyRelative("first").stringValue = @new;
|
||||
newProperty.FindPropertyRelative("second").floatValue = oldValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool RenameKeyword(SerializedObject so, Material material, string old, string @new)
|
||||
{
|
||||
if (!TryFindProperty(so, old, SerializedType.Keyword, out var oldProperty, out var oldIndex, out var parent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
parent.DeleteArrayElementAtIndex(oldIndex);
|
||||
parent.InsertArrayElementAtIndex(0);
|
||||
var keyword = parent.GetArrayElementAtIndex(0);
|
||||
keyword.stringValue = @new;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Upgrades
|
||||
static partial class MaterialUpgrader
|
||||
{
|
||||
public const int k_MaterialVersion = 1;
|
||||
|
||||
static bool UpgradeMaterial(Material material, int version)
|
||||
{
|
||||
var so = new SerializedObject(material);
|
||||
var dirty = false;
|
||||
|
||||
// Upgrade materials.
|
||||
// Version is for all materials.
|
||||
if (version < 1)
|
||||
{
|
||||
switch (material.shader.name)
|
||||
{
|
||||
case "Crest/Water":
|
||||
dirty |= RenameKeyword(so, material, "CREST_FLOW_ON", "_CREST_FLOW_LOD");
|
||||
dirty |= RenameFloat(so, material, "CREST_FLOW", "_CREST_FLOW_LOD");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty)
|
||||
{
|
||||
so.ApplyModifiedPropertiesWithoutUndo();
|
||||
EditorUtility.SetDirty(material);
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c96ae7831f600451a8b0c5326b10ac54
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -2,7 +2,6 @@
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using WaveHarmonic.Crest.Editor.Settings;
|
||||
|
||||
namespace WaveHarmonic.Crest.Editor
|
||||
{
|
||||
@@ -30,21 +29,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
_ => throw new System.NotImplementedException(),
|
||||
};
|
||||
|
||||
internal bool GetProjectSettingToggle() => PropertyName switch
|
||||
{
|
||||
nameof(WaterRenderer._AbsorptionLod) => ProjectSettings.Instance.CurrentPlatformSettings.AbsorptionSimulation,
|
||||
nameof(WaterRenderer._AlbedoLod) => ProjectSettings.Instance.CurrentPlatformSettings.AlbedoSimulation,
|
||||
nameof(WaterRenderer._AnimatedWavesLod) => true,
|
||||
nameof(WaterRenderer._ClipLod) => true,
|
||||
nameof(WaterRenderer._DepthLod) => true,
|
||||
nameof(WaterRenderer._DynamicWavesLod) => true,
|
||||
nameof(WaterRenderer._FlowLod) => true,
|
||||
nameof(WaterRenderer._FoamLod) => true,
|
||||
nameof(WaterRenderer._LevelLod) => true,
|
||||
nameof(WaterRenderer._ScatteringLod) => ProjectSettings.Instance.CurrentPlatformSettings.ScatteringSimulation,
|
||||
nameof(WaterRenderer._ShadowLod) => ProjectSettings.Instance.CurrentPlatformSettings.ShadowSimulation,
|
||||
_ => throw new System.NotImplementedException(),
|
||||
};
|
||||
|
||||
// Optional. Not all simulations will have a corresponding keyword.
|
||||
internal bool HasMaterialToggle => !string.IsNullOrEmpty(MaterialProperty);
|
||||
@@ -52,7 +36,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
// Needed as clip surface material toggle is Alpha Clipping.
|
||||
internal virtual string MaterialProperty => _MaterialProperty;
|
||||
internal virtual string MaterialPropertyPath => $"{PropertyLabel} > Enabled";
|
||||
internal virtual string MaterialKeyword => MaterialProperty;
|
||||
internal virtual string MaterialKeyword => $"{MaterialProperty}_ON";
|
||||
|
||||
internal static OptionalLod Get(System.Type type)
|
||||
{
|
||||
@@ -110,7 +94,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
{
|
||||
PropertyLabel = "Flow",
|
||||
PropertyName = nameof(WaterRenderer._FlowLod),
|
||||
_MaterialProperty = "_CREST_FLOW_LOD",
|
||||
_MaterialProperty = "CREST_FLOW",
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -126,7 +110,9 @@ namespace WaveHarmonic.Crest.Editor
|
||||
{
|
||||
PropertyLabel = "Water Level",
|
||||
PropertyName = nameof(WaterRenderer._LevelLod),
|
||||
_MaterialProperty = "_Crest_LevelEnabled",
|
||||
Dependency = typeof(AnimatedWavesLod),
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -167,13 +153,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
// BIRP SG has prefixes for Unity properties but other RPs do not. These prefixes
|
||||
// are for serialisation only and are not used in the shader.
|
||||
internal override string MaterialPropertyPath => "Alpha Clipping";
|
||||
internal override string MaterialProperty => RenderPipelineHelper.RenderPipeline switch
|
||||
{
|
||||
RenderPipeline.Legacy => "_BUILTIN_AlphaClip",
|
||||
RenderPipeline.HighDefinition => "_AlphaCutoffEnable",
|
||||
RenderPipeline.Universal => "_AlphaClip",
|
||||
_ => throw new System.NotImplementedException(),
|
||||
};
|
||||
internal override string MaterialProperty => (RenderPipelineHelper.IsLegacy ? "_BUILTIN" : "") + "_AlphaClip";
|
||||
internal override string MaterialKeyword => (RenderPipelineHelper.IsLegacy ? "_BUILTIN" : "") + "_ALPHATEST_ON";
|
||||
}
|
||||
|
||||
|
||||
@@ -57,10 +57,10 @@ namespace WaveHarmonic.Crest.Editor
|
||||
|
||||
public override void OnPreviewGUI(Rect rect, GUIStyle background)
|
||||
{
|
||||
var texture = (RenderTexture)OriginalTexture;
|
||||
var texture = Lod.DataTexture;
|
||||
var descriptor = texture.descriptor;
|
||||
_TemporaryTexture = RenderTexture.GetTemporary(descriptor);
|
||||
_TemporaryTexture.name = texture.name;
|
||||
_TemporaryTexture.name = "Crest Preview (Temporary)";
|
||||
Graphics.CopyTexture(texture, _TemporaryTexture);
|
||||
|
||||
if (VisualizeNegatives)
|
||||
@@ -80,16 +80,15 @@ namespace WaveHarmonic.Crest.Editor
|
||||
if (ForceAlpha)
|
||||
{
|
||||
// Set alpha to one otherwise it shows nothing when set to RGB.
|
||||
if (WaterResources.Instance.Compute._Clear != null)
|
||||
var clear = WaterResources.Instance.Compute._Clear;
|
||||
if (clear != null)
|
||||
{
|
||||
var compute = WaterResources.Instance._ComputeLibrary._ClearCompute;
|
||||
var wrapper = new PropertyWrapperComputeStandalone(compute._Shader, compute._KernelClearTarget);
|
||||
compute.SetVariantForFormat(wrapper, _TemporaryTexture.graphicsFormat);
|
||||
wrapper.SetTexture(ShaderIDs.s_Target, _TemporaryTexture);
|
||||
wrapper.SetVector(ShaderIDs.s_ClearMask, Color.black);
|
||||
wrapper.SetVector(ShaderIDs.s_ClearColor, Color.black);
|
||||
wrapper.Dispatch
|
||||
clear.SetTexture(0, ShaderIDs.s_Target, _TemporaryTexture);
|
||||
clear.SetVector(ShaderIDs.s_ClearMask, Color.black);
|
||||
clear.SetVector(ShaderIDs.s_ClearColor, Color.black);
|
||||
clear.Dispatch
|
||||
(
|
||||
0,
|
||||
Lod.Resolution / Lod.k_ThreadGroupSizeX,
|
||||
Lod.Resolution / Lod.k_ThreadGroupSizeY,
|
||||
Lod.Slices
|
||||
@@ -291,16 +290,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
|
||||
public override GUIContent GetPreviewTitle() => new("Water Reflections");
|
||||
protected override Texture OriginalTexture => (target as WaterRenderer)._Reflections._Enabled
|
||||
? (target as WaterRenderer)._Reflections.ColorTexture
|
||||
? (target as WaterRenderer)._Reflections.ReflectionTexture
|
||||
: s_DefaultReflection?.GetValue(null) as Texture;
|
||||
}
|
||||
|
||||
#if CREST_DEBUG
|
||||
[CustomPreview(typeof(WaterRenderer))]
|
||||
sealed class ReflectionDepthPreview : TexturePreview
|
||||
{
|
||||
public override GUIContent GetPreviewTitle() => new("Water Reflections (Depth)");
|
||||
protected override Texture OriginalTexture => (target as WaterRenderer)._Reflections.DepthTexture;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -10,134 +10,14 @@ using UnityEngine.UIElements;
|
||||
|
||||
namespace WaveHarmonic.Crest.Editor.Settings
|
||||
{
|
||||
[System.Serializable]
|
||||
class PlatformSettings
|
||||
{
|
||||
const string k_OverrideTooltip = "Override the feature for this platform";
|
||||
|
||||
[HideInInspector]
|
||||
[SerializeField]
|
||||
internal bool _Default;
|
||||
|
||||
|
||||
[@Heading("Simulations", alwaysVisible: true)]
|
||||
|
||||
[Tooltip(k_OverrideTooltip)]
|
||||
[@Predicated(nameof(_Default), inverted: true, hide: true)]
|
||||
[@InlineToggle]
|
||||
[SerializeField]
|
||||
internal bool _OverrideAlbedoSimulation;
|
||||
|
||||
[@Label("Albedo")]
|
||||
[@DecoratedField]
|
||||
[SerializeField]
|
||||
internal bool _AlbedoSimulation = true;
|
||||
|
||||
[Tooltip(k_OverrideTooltip)]
|
||||
[@Predicated(nameof(_Default), inverted: true, hide: true)]
|
||||
[@InlineToggle]
|
||||
[SerializeField]
|
||||
internal bool _OverrideAbsorptionSimulation;
|
||||
|
||||
[@Label("Absorption")]
|
||||
[@DecoratedField]
|
||||
[SerializeField]
|
||||
internal bool _AbsorptionSimulation = true;
|
||||
|
||||
[Tooltip(k_OverrideTooltip)]
|
||||
[@Predicated(nameof(_Default), inverted: true, hide: true)]
|
||||
[@InlineToggle]
|
||||
[SerializeField]
|
||||
internal bool _OverrideScatteringSimulation;
|
||||
|
||||
[@Label("Scattering")]
|
||||
[@DecoratedField]
|
||||
[SerializeField]
|
||||
internal bool _ScatteringSimulation = true;
|
||||
|
||||
[Tooltip(k_OverrideTooltip)]
|
||||
[@Predicated(nameof(_Default), inverted: true, hide: true)]
|
||||
[@InlineToggle]
|
||||
[SerializeField]
|
||||
internal bool _OverrideShadowSimulation;
|
||||
|
||||
[@Label("Shadow")]
|
||||
[@DecoratedField]
|
||||
[SerializeField]
|
||||
internal bool _ShadowSimulation = true;
|
||||
|
||||
|
||||
[@Heading("Surface Material", alwaysVisible: true)]
|
||||
|
||||
[Tooltip(k_OverrideTooltip)]
|
||||
[@Predicated(nameof(_Default), inverted: true, hide: true)]
|
||||
[@InlineToggle]
|
||||
[SerializeField]
|
||||
internal bool _OverrideNormalMaps;
|
||||
|
||||
[@DecoratedField]
|
||||
[SerializeField]
|
||||
internal bool _NormalMaps = true;
|
||||
|
||||
[Tooltip(k_OverrideTooltip)]
|
||||
[@Predicated(nameof(_Default), inverted: true, hide: true)]
|
||||
[@InlineToggle]
|
||||
[SerializeField]
|
||||
internal bool _OverridePlanarReflections;
|
||||
|
||||
[@DecoratedField]
|
||||
[SerializeField]
|
||||
internal bool _PlanarReflections = true;
|
||||
|
||||
[Tooltip(k_OverrideTooltip)]
|
||||
[@Predicated(nameof(_Default), inverted: true, hide: true)]
|
||||
[@InlineToggle]
|
||||
[SerializeField]
|
||||
internal bool _OverrideFoamBioluminescence;
|
||||
|
||||
[@DecoratedField]
|
||||
[SerializeField]
|
||||
internal bool _FoamBioluminescence = true;
|
||||
|
||||
[Tooltip(k_OverrideTooltip)]
|
||||
[@Predicated(nameof(_Default), inverted: true, hide: true)]
|
||||
[@InlineToggle]
|
||||
[SerializeField]
|
||||
internal bool _OverrideCausticsForceDistortion;
|
||||
|
||||
[@DecoratedField]
|
||||
[SerializeField]
|
||||
internal bool _CausticsForceDistortion = true;
|
||||
|
||||
|
||||
[@Heading("Rendering", alwaysVisible: true)]
|
||||
|
||||
[Tooltip(k_OverrideTooltip)]
|
||||
[@Predicated(nameof(_Default), inverted: true, hide: true)]
|
||||
[@InlineToggle]
|
||||
[SerializeField]
|
||||
internal bool _OverrideSimpleTransparency;
|
||||
|
||||
[@DecoratedField]
|
||||
[SerializeField]
|
||||
internal bool _SimpleTransparency;
|
||||
|
||||
PlatformSettings Default => ProjectSettings.Instance._PlatformSettings;
|
||||
|
||||
public bool AlbedoSimulation => _Default || _OverrideAlbedoSimulation ? _AlbedoSimulation : Default.AlbedoSimulation;
|
||||
public bool AbsorptionSimulation => _Default || _OverrideAbsorptionSimulation ? _AbsorptionSimulation : Default.AbsorptionSimulation;
|
||||
public bool ScatteringSimulation => _Default || _OverrideScatteringSimulation ? _ScatteringSimulation : Default.ScatteringSimulation;
|
||||
public bool ShadowSimulation => _Default || _OverrideShadowSimulation ? _ShadowSimulation : Default.ShadowSimulation;
|
||||
public bool NormalMaps => _Default || _OverrideNormalMaps ? _NormalMaps : Default.NormalMaps;
|
||||
public bool PlanarReflections => _Default || _OverridePlanarReflections ? _PlanarReflections : Default.PlanarReflections;
|
||||
public bool FoamBioluminescence => _Default || _OverrideFoamBioluminescence ? _FoamBioluminescence : Default.FoamBioluminescence;
|
||||
public bool CausticsForceDistortion => _Default || _OverrideCausticsForceDistortion ? _CausticsForceDistortion : Default.CausticsForceDistortion;
|
||||
public bool SimpleTransparency => _Default || _OverrideSimpleTransparency ? _SimpleTransparency : Default.SimpleTransparency;
|
||||
}
|
||||
|
||||
[FilePath(k_Path, FilePathAttribute.Location.ProjectFolder)]
|
||||
sealed partial class ProjectSettings : ScriptableSingleton<ProjectSettings>
|
||||
sealed class ProjectSettings : ScriptableSingleton<ProjectSettings>
|
||||
{
|
||||
[SerializeField, HideInInspector]
|
||||
#pragma warning disable 414
|
||||
int _Version = 0;
|
||||
#pragma warning restore 414
|
||||
|
||||
#pragma warning disable IDE0032 // Use auto property
|
||||
|
||||
[@Heading("Variant Stripping", Heading.Style.Settings)]
|
||||
@@ -171,86 +51,6 @@ namespace WaveHarmonic.Crest.Editor.Settings
|
||||
[@DecoratedField, SerializeField]
|
||||
bool _LegacyUnderwater;
|
||||
|
||||
[@Space(10)]
|
||||
|
||||
[@PlatformTabs]
|
||||
[SerializeField]
|
||||
internal int _Platforms;
|
||||
|
||||
[@Label("Overriden Settings for Windows, Mac and Linux")]
|
||||
[@Predicated(nameof(_Platforms), inverted: true, (int)BuildTargetGroup.Standalone, hide: true)]
|
||||
[@Stripped(Stripped.Style.PlatformTab, indent: true)]
|
||||
[SerializeField]
|
||||
internal PlatformSettings _PlatformSettingsDesktop = new();
|
||||
|
||||
[@Label("Overriden Settings for Dedicated Server")]
|
||||
[@Predicated(nameof(_Platforms), inverted: true, -2, hide: true)]
|
||||
[@Stripped(Stripped.Style.PlatformTab, indent: true)]
|
||||
[SerializeField]
|
||||
internal PlatformSettings _PlatformSettingsServer = new();
|
||||
|
||||
[@Label("Overriden Settings for Android")]
|
||||
[@Predicated(nameof(_Platforms), inverted: true, (int)BuildTargetGroup.Android, hide: true)]
|
||||
[@Stripped(Stripped.Style.PlatformTab, indent: true)]
|
||||
[SerializeField]
|
||||
internal PlatformSettings _PlatformSettingsAndroid = new();
|
||||
|
||||
[@Label("Overriden Settings for iOS")]
|
||||
[@Predicated(nameof(_Platforms), inverted: true, (int)BuildTargetGroup.iOS, hide: true)]
|
||||
[@Stripped(Stripped.Style.PlatformTab, indent: true)]
|
||||
[SerializeField]
|
||||
internal PlatformSettings _PlatformSettingsIOS = new();
|
||||
|
||||
[@Label("Overriden Settings for tvOS")]
|
||||
[@Predicated(nameof(_Platforms), inverted: true, (int)BuildTargetGroup.tvOS, hide: true)]
|
||||
[@Stripped(Stripped.Style.PlatformTab, indent: true)]
|
||||
[SerializeField]
|
||||
internal PlatformSettings _PlatformSettingsTVOS = new();
|
||||
|
||||
[@Label("Overriden Settings for visionOS")]
|
||||
[@Predicated(nameof(_Platforms), inverted: true, (int)BuildTargetGroup.VisionOS, hide: true)]
|
||||
[@Stripped(Stripped.Style.PlatformTab, indent: true)]
|
||||
[SerializeField]
|
||||
internal PlatformSettings _PlatformSettingsVisionOS = new();
|
||||
|
||||
// Web has hard limitations on number of sampled textures. Set defaults with that
|
||||
// in mind so the surface renders.
|
||||
[@Label("Overriden Settings for Web")]
|
||||
[@Predicated(nameof(_Platforms), inverted: true, (int)BuildTargetGroup.WebGL, hide: true)]
|
||||
[@Stripped(Stripped.Style.PlatformTab, indent: true)]
|
||||
[SerializeField]
|
||||
internal PlatformSettings _PlatformSettingsWeb = new()
|
||||
{
|
||||
_OverrideAbsorptionSimulation = true,
|
||||
_AbsorptionSimulation = false,
|
||||
_OverrideAlbedoSimulation = true,
|
||||
_AlbedoSimulation = false,
|
||||
_OverrideScatteringSimulation = true,
|
||||
_ScatteringSimulation = false,
|
||||
_OverrideShadowSimulation = true,
|
||||
_ShadowSimulation = false,
|
||||
|
||||
_OverrideCausticsForceDistortion = true,
|
||||
_CausticsForceDistortion = false,
|
||||
_OverridePlanarReflections = true,
|
||||
_PlanarReflections = false,
|
||||
_OverrideFoamBioluminescence = true,
|
||||
_FoamBioluminescence = false,
|
||||
};
|
||||
|
||||
// This will show if nothing else shows.
|
||||
[@Label("Default Settings")]
|
||||
[@Predicated(nameof(_Platforms), inverted: false, (int)BuildTargetGroup.Standalone, hide: true)]
|
||||
[@Predicated(nameof(_Platforms), inverted: false, Reflected.BuildTargetGroup.k_Server, hide: true)]
|
||||
[@Predicated(nameof(_Platforms), inverted: false, (int)BuildTargetGroup.Android, hide: true)]
|
||||
[@Predicated(nameof(_Platforms), inverted: false, (int)BuildTargetGroup.iOS, hide: true)]
|
||||
[@Predicated(nameof(_Platforms), inverted: false, (int)BuildTargetGroup.WebGL, hide: true)]
|
||||
[@Predicated(nameof(_Platforms), inverted: false, (int)BuildTargetGroup.tvOS, hide: true)]
|
||||
[@Predicated(nameof(_Platforms), inverted: false, (int)BuildTargetGroup.VisionOS, hide: true)]
|
||||
[@Stripped(Stripped.Style.PlatformTab, indent: true)]
|
||||
[SerializeField]
|
||||
internal PlatformSettings _PlatformSettings = new() { _Default = true };
|
||||
|
||||
#pragma warning restore IDE0032 // Use auto property
|
||||
|
||||
internal const string k_Path = "ProjectSettings/Packages/com.waveharmonic.crest/Settings.asset";
|
||||
@@ -272,24 +72,6 @@ namespace WaveHarmonic.Crest.Editor.Settings
|
||||
internal bool RenderAtmosphericScatteringWhenUnderWater => _RenderAtmosphericScatteringWhenUnderWater;
|
||||
internal bool LegacyUnderwater => _LegacyUnderwater;
|
||||
|
||||
internal PlatformSettings CurrentPlatformSettings =>
|
||||
#if PLATFORM_STANDALONE
|
||||
_PlatformSettingsDesktop;
|
||||
#elif PLATFORM_SERVER
|
||||
_PlatformSettingsServer;
|
||||
#elif PLATFORM_ANDROID
|
||||
_PlatformSettingsAndroid;
|
||||
#elif PLATFORM_IOS
|
||||
_PlatformSettingsIOS;
|
||||
#elif PLATFORM_TVOS
|
||||
_PlatformSettingsTVOS;
|
||||
#elif PLATFORM_VISIONOS
|
||||
_PlatformSettingsVisionOS;
|
||||
#else
|
||||
_PlatformSettings;
|
||||
#endif
|
||||
|
||||
internal bool _IsPlatformTabChange;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
@@ -306,14 +88,6 @@ namespace WaveHarmonic.Crest.Editor.Settings
|
||||
[@OnChange(skipIfInactive: false)]
|
||||
void OnChange(string path, object previous)
|
||||
{
|
||||
_IsPlatformTabChange = path == nameof(_Platforms);
|
||||
|
||||
if (path.StartsWithNoAlloc("_PlatformSettings"))
|
||||
{
|
||||
UpdateSymbols();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (path)
|
||||
{
|
||||
case nameof(_FullPrecisionDisplacementOnHalfPrecisionPlatforms):
|
||||
@@ -327,7 +101,6 @@ namespace WaveHarmonic.Crest.Editor.Settings
|
||||
void UpdateScriptingSymbols()
|
||||
{
|
||||
ScriptingSymbols.Set(ProjectSymbols.k_LegacyUnderwaterScriptingSymbol, _LegacyUnderwater);
|
||||
ScriptingSymbols.Set(ProjectSymbols.k_SimpleTransparencyScriptingSymbol, CurrentPlatformSettings.SimpleTransparency);
|
||||
}
|
||||
|
||||
void UpdateSymbols()
|
||||
@@ -339,7 +112,6 @@ namespace WaveHarmonic.Crest.Editor.Settings
|
||||
sealed class ProjectSymbols : AssetModificationProcessor
|
||||
{
|
||||
public const string k_LegacyUnderwaterScriptingSymbol = "d_Crest_LegacyUnderwater";
|
||||
public const string k_SimpleTransparencyScriptingSymbol = "d_Crest_SimpleTransparency";
|
||||
|
||||
static FileSystemWatcher s_Watcher;
|
||||
|
||||
@@ -370,11 +142,6 @@ namespace WaveHarmonic.Crest.Editor.Settings
|
||||
{
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
if (ProjectSettings.Instance != null && ProjectSettings.Instance._IsPlatformTabChange)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Destroy instance to reflect changes.
|
||||
Helpers.Destroy(Instance);
|
||||
typeof(ScriptableSingleton<ProjectSettings>)
|
||||
@@ -453,17 +220,31 @@ namespace WaveHarmonic.Crest.Editor.Settings
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset foldout values.
|
||||
DecoratedDrawer.s_IsFoldout = false;
|
||||
DecoratedDrawer.s_IsFoldoutOpen = false;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
// Pad similar to settings header.
|
||||
var style = new GUIStyle();
|
||||
style.padding.left = 8;
|
||||
EditorGUILayout.BeginVertical(style);
|
||||
|
||||
// Same label with as other settings.
|
||||
EditorGUIUtility.labelWidth = 251;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
EditorGUILayout.BeginVertical(style);
|
||||
_Editor.OnInspectorGUI();
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
// Commit all changes. Normally settings are written when user hits save or exits
|
||||
// without any undo/redo entry and dirty state. No idea how to do the same.
|
||||
// SaveChanges and hasUnsavedChanges on custom editor did not work.
|
||||
// Not sure if hooking into EditorSceneManager.sceneSaving is correct.
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
ProjectSettings.Save();
|
||||
}
|
||||
|
||||
GUILayout.Space(10 * 2);
|
||||
|
||||
@@ -475,8 +256,6 @@ namespace WaveHarmonic.Crest.Editor.Settings
|
||||
AssetDatabase.ImportAsset(path);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
[SettingsProvider]
|
||||
@@ -493,43 +272,4 @@ namespace WaveHarmonic.Crest.Editor.Settings
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(ProjectSettings))]
|
||||
class ProjectSettingsEditor : Inspector
|
||||
{
|
||||
protected override void OnChange()
|
||||
{
|
||||
base.OnChange();
|
||||
|
||||
// Commit all changes. Normally settings are written when user hits save or exits
|
||||
// without any undo/redo entry and dirty state. No idea how to do the same.
|
||||
// SaveChanges and hasUnsavedChanges on custom editor did not work.
|
||||
// Not sure if hooking into EditorSceneManager.sceneSaving is correct.
|
||||
ProjectSettings.Save();
|
||||
}
|
||||
}
|
||||
|
||||
partial class ProjectSettings : ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField, HideInInspector]
|
||||
int _Version = 0;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
internal int _MaterialVersion = MaterialUpgrader.k_MaterialVersion;
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
if (_Version == 0)
|
||||
{
|
||||
_MaterialVersion = 0;
|
||||
}
|
||||
|
||||
_Version = 1;
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,22 +14,22 @@
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.waveharmonic.crest.cpu-queries",
|
||||
"expression": "(,1.0.9)",
|
||||
"expression": "(,1.0.8)",
|
||||
"define": "d_UpdateCPUQueries"
|
||||
},
|
||||
{
|
||||
"name": "com.waveharmonic.crest.paint",
|
||||
"expression": "(,1.3.0)",
|
||||
"expression": "(,1.2.3)",
|
||||
"define": "d_UpdatePaint"
|
||||
},
|
||||
{
|
||||
"name": "com.waveharmonic.crest.portals",
|
||||
"expression": "(,1.2.9)",
|
||||
"expression": "(,1.2.8)",
|
||||
"define": "d_UpdatePortals"
|
||||
},
|
||||
{
|
||||
"name": "com.waveharmonic.crest.shallow-water",
|
||||
"expression": "(,1.4.0)",
|
||||
"expression": "(,1.3.3)",
|
||||
"define": "d_UpdateShallowWater"
|
||||
},
|
||||
{
|
||||
@@ -39,12 +39,12 @@
|
||||
},
|
||||
{
|
||||
"name": "com.waveharmonic.crest.splines",
|
||||
"expression": "(,1.5.0)",
|
||||
"expression": "(,1.4.4)",
|
||||
"define": "d_UpdateSplines"
|
||||
},
|
||||
{
|
||||
"name": "com.waveharmonic.crest.whirlpool",
|
||||
"expression": "(,1.1.0)",
|
||||
"expression": "(,1.0.3)",
|
||||
"define": "d_UpdateWhirlpool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
}
|
||||
}
|
||||
|
||||
[GenerateHLSL(sourcePath = "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings/Settings.Crest")]
|
||||
[GenerateHLSL(sourcePath = "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings.Crest")]
|
||||
sealed class ShaderSettings
|
||||
{
|
||||
// These two are here for compute shaders.
|
||||
@@ -126,191 +126,10 @@ namespace WaveHarmonic.Crest.Editor
|
||||
#endif
|
||||
;
|
||||
|
||||
// Active when build target is activated:
|
||||
// https://docs.unity3d.com/6000.3/Documentation/Manual/scripting-symbol-reference.html
|
||||
|
||||
public static int s_CrestPlatformStandalone =
|
||||
#if PLATFORM_STANDALONE
|
||||
1 +
|
||||
#endif
|
||||
0;
|
||||
|
||||
public static int s_CrestPlatformServer =
|
||||
#if PLATFORM_SERVER
|
||||
1 +
|
||||
#endif
|
||||
0;
|
||||
|
||||
public static int s_CrestPlatformAndroid =
|
||||
#if PLATFORM_ANDROID
|
||||
1 +
|
||||
#endif
|
||||
0;
|
||||
|
||||
public static int s_CrestPlatformIOS =
|
||||
#if PLATFORM_IOS
|
||||
1 +
|
||||
#endif
|
||||
0;
|
||||
|
||||
public static int s_CrestPlatformWeb =
|
||||
#if PLATFORM_WEBGL
|
||||
1 +
|
||||
#endif
|
||||
0;
|
||||
|
||||
public static int s_CrestPlatformTVOS =
|
||||
#if PLATFORM_TVOS
|
||||
1 +
|
||||
#endif
|
||||
0;
|
||||
|
||||
public static int s_CrestPlatformVISIONOS =
|
||||
#if PLATFORM_VISIONOS
|
||||
1 +
|
||||
#endif
|
||||
0;
|
||||
|
||||
public static int s_CrestFullPrecisionDisplacement = ProjectSettings.Instance.FullPrecisionDisplacementOnHalfPrecisionPlatforms ? 1 : 0;
|
||||
|
||||
public static int s_CrestDiscardAtmosphericScattering = ProjectSettings.Instance.RenderAtmosphericScatteringWhenUnderWater ? 0 : 1;
|
||||
|
||||
public static int s_CrestLegacyUnderwater = ProjectSettings.Instance.LegacyUnderwater ? 1 : 0;
|
||||
}
|
||||
|
||||
[GenerateHLSL(sourcePath = "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings/Settings.Crest.Default")]
|
||||
sealed class ShaderSettingsDefault
|
||||
{
|
||||
static PlatformSettings Settings => ProjectSettings.Instance._PlatformSettings;
|
||||
|
||||
public static int s_CrestAlbedoSimulation = Settings.AlbedoSimulation ? 1 : 0;
|
||||
public static int s_CrestAbsorptionSimulation = Settings.AbsorptionSimulation ? 1 : 0;
|
||||
public static int s_CrestScatteringSimulation = Settings.ScatteringSimulation ? 1 : 0;
|
||||
public static int s_CrestShadowSimulation = Settings.ShadowSimulation ? 1 : 0;
|
||||
|
||||
public static int s_CrestCausticsForceDistortion = Settings.CausticsForceDistortion ? 1 : 0;
|
||||
public static int s_CrestFoamBioluminescence = Settings.FoamBioluminescence ? 1 : 0;
|
||||
public static int s_CrestNormalMaps = Settings.NormalMaps ? 1 : 0;
|
||||
public static int s_CrestSimpleTransparency = Settings.SimpleTransparency ? 1 : 0;
|
||||
public static int s_CrestPlanarReflections = Settings.PlanarReflections ? 1 : 0;
|
||||
}
|
||||
|
||||
[GenerateHLSL(sourcePath = "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings/Settings.Crest.Standalone")]
|
||||
sealed class ShaderSettingsStandalone
|
||||
{
|
||||
static PlatformSettings Settings => ProjectSettings.Instance._PlatformSettingsDesktop;
|
||||
|
||||
public static int s_CrestAlbedoSimulation = Settings.AlbedoSimulation ? 1 : 0;
|
||||
public static int s_CrestAbsorptionSimulation = Settings.AbsorptionSimulation ? 1 : 0;
|
||||
public static int s_CrestScatteringSimulation = Settings.ScatteringSimulation ? 1 : 0;
|
||||
public static int s_CrestShadowSimulation = Settings.ShadowSimulation ? 1 : 0;
|
||||
|
||||
public static int s_CrestCausticsForceDistortion = Settings.CausticsForceDistortion ? 1 : 0;
|
||||
public static int s_CrestFoamBioluminescence = Settings.FoamBioluminescence ? 1 : 0;
|
||||
public static int s_CrestNormalMaps = Settings.NormalMaps ? 1 : 0;
|
||||
public static int s_CrestSimpleTransparency = Settings.SimpleTransparency ? 1 : 0;
|
||||
public static int s_CrestPlanarReflections = Settings.PlanarReflections ? 1 : 0;
|
||||
}
|
||||
|
||||
[GenerateHLSL(sourcePath = "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings/Settings.Crest.Server")]
|
||||
sealed class ShaderSettingsServer
|
||||
{
|
||||
static PlatformSettings Settings => ProjectSettings.Instance._PlatformSettingsServer;
|
||||
|
||||
public static int s_CrestAlbedoSimulation = Settings.AlbedoSimulation ? 1 : 0;
|
||||
public static int s_CrestAbsorptionSimulation = Settings.AbsorptionSimulation ? 1 : 0;
|
||||
public static int s_CrestScatteringSimulation = Settings.ScatteringSimulation ? 1 : 0;
|
||||
public static int s_CrestShadowSimulation = Settings.ShadowSimulation ? 1 : 0;
|
||||
|
||||
public static int s_CrestCausticsForceDistortion = Settings.CausticsForceDistortion ? 1 : 0;
|
||||
public static int s_CrestFoamBioluminescence = Settings.FoamBioluminescence ? 1 : 0;
|
||||
public static int s_CrestNormalMaps = Settings.NormalMaps ? 1 : 0;
|
||||
public static int s_CrestSimpleTransparency = Settings.SimpleTransparency ? 1 : 0;
|
||||
public static int s_CrestPlanarReflections = Settings.PlanarReflections ? 1 : 0;
|
||||
}
|
||||
|
||||
[GenerateHLSL(sourcePath = "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings/Settings.Crest.Android")]
|
||||
sealed class ShaderSettingsAndroid
|
||||
{
|
||||
static PlatformSettings Settings => ProjectSettings.Instance._PlatformSettingsAndroid;
|
||||
|
||||
public static int s_CrestAlbedoSimulation = Settings.AlbedoSimulation ? 1 : 0;
|
||||
public static int s_CrestAbsorptionSimulation = Settings.AbsorptionSimulation ? 1 : 0;
|
||||
public static int s_CrestScatteringSimulation = Settings.ScatteringSimulation ? 1 : 0;
|
||||
public static int s_CrestShadowSimulation = Settings.ShadowSimulation ? 1 : 0;
|
||||
|
||||
public static int s_CrestCausticsForceDistortion = Settings.CausticsForceDistortion ? 1 : 0;
|
||||
public static int s_CrestFoamBioluminescence = Settings.FoamBioluminescence ? 1 : 0;
|
||||
public static int s_CrestNormalMaps = Settings.NormalMaps ? 1 : 0;
|
||||
public static int s_CrestSimpleTransparency = Settings.SimpleTransparency ? 1 : 0;
|
||||
public static int s_CrestPlanarReflections = Settings.PlanarReflections ? 1 : 0;
|
||||
}
|
||||
|
||||
[GenerateHLSL(sourcePath = "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings/Settings.Crest.iOS")]
|
||||
sealed class ShaderSettingsIOS
|
||||
{
|
||||
static PlatformSettings Settings => ProjectSettings.Instance._PlatformSettingsIOS;
|
||||
|
||||
public static int s_CrestAlbedoSimulation = Settings.AlbedoSimulation ? 1 : 0;
|
||||
public static int s_CrestAbsorptionSimulation = Settings.AbsorptionSimulation ? 1 : 0;
|
||||
public static int s_CrestScatteringSimulation = Settings.ScatteringSimulation ? 1 : 0;
|
||||
public static int s_CrestShadowSimulation = Settings.ShadowSimulation ? 1 : 0;
|
||||
|
||||
public static int s_CrestCausticsForceDistortion = Settings.CausticsForceDistortion ? 1 : 0;
|
||||
public static int s_CrestFoamBioluminescence = Settings.FoamBioluminescence ? 1 : 0;
|
||||
public static int s_CrestNormalMaps = Settings.NormalMaps ? 1 : 0;
|
||||
public static int s_CrestSimpleTransparency = Settings.SimpleTransparency ? 1 : 0;
|
||||
public static int s_CrestPlanarReflections = Settings.PlanarReflections ? 1 : 0;
|
||||
}
|
||||
|
||||
[GenerateHLSL(sourcePath = "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings/Settings.Crest.Web")]
|
||||
sealed class ShaderSettingsWeb
|
||||
{
|
||||
static PlatformSettings Settings => ProjectSettings.Instance._PlatformSettingsWeb;
|
||||
|
||||
public static int s_CrestAlbedoSimulation = Settings.AlbedoSimulation ? 1 : 0;
|
||||
public static int s_CrestAbsorptionSimulation = Settings.AbsorptionSimulation ? 1 : 0;
|
||||
public static int s_CrestScatteringSimulation = Settings.ScatteringSimulation ? 1 : 0;
|
||||
public static int s_CrestShadowSimulation = Settings.ShadowSimulation ? 1 : 0;
|
||||
|
||||
public static int s_CrestCausticsForceDistortion = Settings.CausticsForceDistortion ? 1 : 0;
|
||||
public static int s_CrestFoamBioluminescence = Settings.FoamBioluminescence ? 1 : 0;
|
||||
public static int s_CrestNormalMaps = Settings.NormalMaps ? 1 : 0;
|
||||
public static int s_CrestSimpleTransparency = Settings.SimpleTransparency ? 1 : 0;
|
||||
public static int s_CrestPlanarReflections = Settings.PlanarReflections ? 1 : 0;
|
||||
}
|
||||
|
||||
[GenerateHLSL(sourcePath = "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings/Settings.Crest.tvOS")]
|
||||
sealed class ShaderSettingsTVOS
|
||||
{
|
||||
static PlatformSettings Settings => ProjectSettings.Instance._PlatformSettingsTVOS;
|
||||
|
||||
public static int s_CrestAlbedoSimulation = Settings.AlbedoSimulation ? 1 : 0;
|
||||
public static int s_CrestAbsorptionSimulation = Settings.AbsorptionSimulation ? 1 : 0;
|
||||
public static int s_CrestScatteringSimulation = Settings.ScatteringSimulation ? 1 : 0;
|
||||
public static int s_CrestShadowSimulation = Settings.ShadowSimulation ? 1 : 0;
|
||||
|
||||
public static int s_CrestCausticsForceDistortion = Settings.CausticsForceDistortion ? 1 : 0;
|
||||
public static int s_CrestFoamBioluminescence = Settings.FoamBioluminescence ? 1 : 0;
|
||||
public static int s_CrestNormalMaps = Settings.NormalMaps ? 1 : 0;
|
||||
public static int s_CrestSimpleTransparency = Settings.SimpleTransparency ? 1 : 0;
|
||||
public static int s_CrestPlanarReflections = Settings.PlanarReflections ? 1 : 0;
|
||||
}
|
||||
|
||||
[GenerateHLSL(sourcePath = "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings/Settings.Crest.visionOS")]
|
||||
sealed class ShaderSettingsVisionOS
|
||||
{
|
||||
static PlatformSettings Settings => ProjectSettings.Instance._PlatformSettingsVisionOS;
|
||||
|
||||
public static int s_CrestAlbedoSimulation = Settings.AlbedoSimulation ? 1 : 0;
|
||||
public static int s_CrestAbsorptionSimulation = Settings.AbsorptionSimulation ? 1 : 0;
|
||||
public static int s_CrestScatteringSimulation = Settings.ScatteringSimulation ? 1 : 0;
|
||||
public static int s_CrestShadowSimulation = Settings.ShadowSimulation ? 1 : 0;
|
||||
|
||||
public static int s_CrestCausticsForceDistortion = Settings.CausticsForceDistortion ? 1 : 0;
|
||||
public static int s_CrestFoamBioluminescence = Settings.FoamBioluminescence ? 1 : 0;
|
||||
public static int s_CrestNormalMaps = Settings.NormalMaps ? 1 : 0;
|
||||
public static int s_CrestSimpleTransparency = Settings.SimpleTransparency ? 1 : 0;
|
||||
public static int s_CrestPlanarReflections = Settings.PlanarReflections ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,21 +147,6 @@ namespace WaveHarmonic.Crest
|
||||
/// </summary>
|
||||
sealed class Stripped : DecoratedProperty
|
||||
{
|
||||
public enum Style
|
||||
{
|
||||
None,
|
||||
PlatformTab,
|
||||
}
|
||||
|
||||
readonly bool _KeepIndent;
|
||||
readonly Style _Style;
|
||||
|
||||
public Stripped(Style style = Style.None, bool indent = false)
|
||||
{
|
||||
_KeepIndent = indent;
|
||||
_Style = style;
|
||||
}
|
||||
|
||||
internal override bool NeedsControlRectangle(SerializedProperty property) => false;
|
||||
|
||||
internal override void OnGUI(Rect position, SerializedProperty property, GUIContent label, DecoratedDrawer drawer)
|
||||
@@ -170,33 +155,11 @@ namespace WaveHarmonic.Crest
|
||||
DecoratedDrawer.s_TemporaryColor = true;
|
||||
DecoratedDrawer.s_PreviousColor = GUI.color;
|
||||
|
||||
if (_Style == Style.PlatformTab)
|
||||
{
|
||||
EditorGUI.indentLevel += 1;
|
||||
EditorGUILayout.LabelField(label);
|
||||
EditorGUI.indentLevel -= 1;
|
||||
}
|
||||
|
||||
GUI.color = new(0, 0, 0, 0);
|
||||
|
||||
if (!_KeepIndent) EditorGUI.indentLevel -= 1;
|
||||
EditorGUI.indentLevel -= 1;
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
if (!_KeepIndent) EditorGUI.indentLevel += 1;
|
||||
|
||||
if (_Style == Style.PlatformTab)
|
||||
{
|
||||
EditorGUILayout.Space(4);
|
||||
EditorGUILayout.EndBuildTargetSelectionGrouping();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class PlatformTabs : DecoratedProperty
|
||||
{
|
||||
static readonly GUIContent s_DefaultTab = new(EditorGUIUtility.IconContent("d_Settings").image, "Default");
|
||||
internal override void OnGUI(Rect position, SerializedProperty property, GUIContent label, DecoratedDrawer drawer)
|
||||
{
|
||||
property.intValue = Editor.Reflected.EditorGUILayout.BeginBuildTargetSelectionGrouping(s_DefaultTab);
|
||||
EditorGUI.indentLevel += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,15 +621,29 @@ namespace WaveHarmonic.Crest
|
||||
|
||||
sealed class InlineToggle : DecoratedProperty
|
||||
{
|
||||
// Add extra y offset. Needed for foldouts in foldouts so far.
|
||||
readonly bool _Fix;
|
||||
|
||||
public InlineToggle(bool fix = false)
|
||||
{
|
||||
_Fix = fix;
|
||||
}
|
||||
|
||||
internal override bool NeedsControlRectangle(SerializedProperty property)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
internal override void OnGUI(Rect position, SerializedProperty property, GUIContent label, DecoratedDrawer drawer)
|
||||
{
|
||||
var r = position;
|
||||
r.x -= 16f;
|
||||
|
||||
// Prevent click events blocking next property.
|
||||
// Align with Space offset.
|
||||
if (drawer.Space > 0) r.y += drawer.Space + 2f;
|
||||
if (_Fix) r.y += EditorGUIUtility.singleLineHeight + 2f;
|
||||
// Seems to be needed.
|
||||
r.width = 16f * (1f + EditorGUI.indentLevel);
|
||||
|
||||
// Hide text.
|
||||
r.height = EditorGUIUtility.singleLineHeight;
|
||||
label.text = "";
|
||||
|
||||
using (new EditorGUI.PropertyScope(r, label, property))
|
||||
@@ -677,9 +654,6 @@ namespace WaveHarmonic.Crest
|
||||
property.boolValue = EditorGUI.Toggle(r, property.boolValue);
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
// Pull up next property. Extra space might be margin/padding.
|
||||
GUILayout.Space(-(EditorGUIUtility.singleLineHeight + 2f));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using WaveHarmonic.Crest.Attributes;
|
||||
@@ -24,29 +23,19 @@ namespace WaveHarmonic.Crest.Editor
|
||||
internal static bool s_HideInInspector = false;
|
||||
public static bool s_IsFoldout = false;
|
||||
public static bool s_IsFoldoutOpen = false;
|
||||
public static bool s_IsList = false;
|
||||
|
||||
public static bool s_TemporaryColor;
|
||||
public static Color s_PreviousColor;
|
||||
|
||||
// If instantiating ourselves. Avoids reflection.
|
||||
public PropertyAttribute _Attribute;
|
||||
public FieldInfo _Field;
|
||||
PropertyAttribute Attribute => _Attribute ?? attribute;
|
||||
FieldInfo Field => _Field ?? fieldInfo;
|
||||
|
||||
public float Space { get; private set; }
|
||||
|
||||
UnityEditor.Editor _Editor;
|
||||
Inspector _Inspector;
|
||||
|
||||
List<object> _Decorators = null;
|
||||
List<object> Decorators
|
||||
{
|
||||
get
|
||||
{
|
||||
// Populate list with decorators.
|
||||
_Decorators ??= Field
|
||||
_Decorators ??= fieldInfo
|
||||
.GetCustomAttributes(typeof(Decorator), false)
|
||||
.ToList();
|
||||
|
||||
@@ -55,7 +44,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
}
|
||||
|
||||
List<Attributes.Validator> _Validators = null;
|
||||
List<Attributes.Validator> Validators => _Validators ??= Field
|
||||
List<Attributes.Validator> Validators => _Validators ??= fieldInfo
|
||||
.GetCustomAttributes(typeof(Attributes.Validator), false)
|
||||
.Cast<Attributes.Validator>()
|
||||
.ToList();
|
||||
@@ -74,39 +63,14 @@ namespace WaveHarmonic.Crest.Editor
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
var height = base.GetPropertyHeight(property, label);
|
||||
|
||||
if (property.isArray)
|
||||
{
|
||||
// Constructor caches value and this call retrieves it.
|
||||
var list = ReorderableList.GetReorderableListFromSerializedProperty(property);
|
||||
list ??= new ReorderableList(property.serializedObject, property);
|
||||
// GetHeight does not include bottom buttons height.
|
||||
height = property.isExpanded ? list.GetHeight() + list.footerHeight : height;
|
||||
}
|
||||
|
||||
// Make original control rectangle be invisible because we always create our own. Zero still adds a little
|
||||
// height which becomes noticeable once multiple properties are hidden. This could be some GUI style
|
||||
// property but could not find which one.
|
||||
return s_IsList ? height : -2f;
|
||||
return -2f;
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
// Get the owning editor.
|
||||
if (_Editor == null)
|
||||
{
|
||||
foreach (var editor in ActiveEditorTracker.sharedTracker?.activeEditors)
|
||||
{
|
||||
if (editor.serializedObject == property.serializedObject)
|
||||
{
|
||||
_Editor = editor;
|
||||
_Inspector = editor as Inspector;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store the original GUI state so it can be reset later.
|
||||
var originalColor = GUI.color;
|
||||
var originalEnabled = GUI.enabled;
|
||||
@@ -142,8 +106,8 @@ namespace WaveHarmonic.Crest.Editor
|
||||
attribute.Decorate(position, property, label, this);
|
||||
}
|
||||
|
||||
var a = (DecoratedProperty)Attribute;
|
||||
position = a.NeedsControlRectangle(property) && (!s_IsList || property.isArray)
|
||||
var a = (DecoratedProperty)attribute;
|
||||
position = a.NeedsControlRectangle(property)
|
||||
? EditorGUILayout.GetControlRect(true, EditorGUI.GetPropertyHeight(property, label, true))
|
||||
: position;
|
||||
|
||||
@@ -156,15 +120,11 @@ namespace WaveHarmonic.Crest.Editor
|
||||
label = attribute.BuildLabel(label);
|
||||
}
|
||||
|
||||
var skipChange = Field.FieldType == typeof(UnityEvent) || property.isArray;
|
||||
|
||||
var isExpanded = property.isExpanded;
|
||||
var isUndoRedo = false;
|
||||
var skipChange = fieldInfo.FieldType == typeof(UnityEvent);
|
||||
|
||||
if (!skipChange)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
isUndoRedo = _Inspector != null && _Inspector._UndoRedo;
|
||||
}
|
||||
|
||||
var oldValue = skipChange ? null : property.boxedValue;
|
||||
@@ -175,19 +135,13 @@ namespace WaveHarmonic.Crest.Editor
|
||||
Validators[index].Validate(position, property, label, this, oldValue);
|
||||
}
|
||||
|
||||
if (!skipChange && (EditorGUI.EndChangeCheck() || isUndoRedo))
|
||||
// Guard against foldouts triggering change check due to changing isExpanded.
|
||||
if (!skipChange && EditorGUI.EndChangeCheck() && oldValue != property.boxedValue)
|
||||
{
|
||||
// Apply any changes.
|
||||
if (!isUndoRedo)
|
||||
{
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
|
||||
// Guard against foldouts triggering change check due to changing isExpanded.
|
||||
if (property.isExpanded == isExpanded)
|
||||
{
|
||||
OnChange(property, oldValue);
|
||||
}
|
||||
OnChange(property, oldValue);
|
||||
}
|
||||
|
||||
for (var index = 0; index < Decorators.Count; index++)
|
||||
@@ -252,7 +206,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
var relativePath = string.Join(".", chunks[(i + 1)..]);
|
||||
|
||||
var nestedTarget = nestedProperty.managedReferenceValue;
|
||||
if (nestedTarget == null) continue;
|
||||
var nestedTargetType = nestedTarget.GetType();
|
||||
|
||||
foreach (var (method, attribute) in OnChangeHandlers)
|
||||
|
||||
@@ -294,13 +294,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
width = Mathf.Max(width, minimumWidth);
|
||||
// TODO: Add option to disable this (consistent width).
|
||||
if (!hasDropDown && minimumWidth > 0) width += k_ButtonDropDownWidth;
|
||||
|
||||
// TODO: eyeballed based on Fix button but likely specific to it.
|
||||
if (centerLabel && hasDropDown)
|
||||
{
|
||||
style.padding.left += k_ButtonDropDownWidth / 2;
|
||||
width += k_ButtonDropDownWidth / 3;
|
||||
}
|
||||
if (centerLabel && hasDropDown) style.padding.left += k_ButtonDropDownWidth;
|
||||
|
||||
if (GUILayout.Button(label, style, expandWidth ? GUILayout.ExpandWidth(true) : GUILayout.Width(width)))
|
||||
{
|
||||
|
||||
@@ -9,7 +9,6 @@ using UnityEditor;
|
||||
using UnityEngine;
|
||||
using WaveHarmonic.Crest.Editor.Internal;
|
||||
using WaveHarmonic.Crest.Internal;
|
||||
using WaveHarmonic.Crest.Internal.Compatibility;
|
||||
|
||||
namespace WaveHarmonic.Crest.Editor
|
||||
{
|
||||
@@ -26,7 +25,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
|
||||
readonly Dictionary<FieldInfo, object> _MaterialOwners = new();
|
||||
readonly Dictionary<Material, MaterialEditor> _MaterialEditors = new();
|
||||
readonly Dictionary<string, DecoratedDrawer> _Lists = new();
|
||||
|
||||
public override bool RequiresConstantRepaint() => TexturePreview.s_ActiveInstance?.Open == true;
|
||||
|
||||
@@ -40,9 +38,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
{
|
||||
_MaterialOwners.Clear();
|
||||
|
||||
Undo.undoRedoPerformed -= OnUndoRedo;
|
||||
Undo.undoRedoPerformed += OnUndoRedo;
|
||||
|
||||
foreach (var field in s_AttachMaterialEditors)
|
||||
{
|
||||
var target = (object)this.target;
|
||||
@@ -79,19 +74,12 @@ namespace WaveHarmonic.Crest.Editor
|
||||
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
Undo.undoRedoPerformed -= OnUndoRedo;
|
||||
|
||||
foreach (var (_, editor) in _MaterialEditors)
|
||||
{
|
||||
Helpers.Destroy(editor);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnChange()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void RenderBeforeInspectorGUI()
|
||||
{
|
||||
if (this.target is EditorBehaviour target && target._IsPrefabStageInstance)
|
||||
@@ -111,8 +99,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
using var iterator = serializedObject.GetIterator();
|
||||
if (iterator.NextVisible(true))
|
||||
{
|
||||
@@ -154,33 +140,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
using (new EditorGUI.DisabledGroupScope(property.name == "m_Script"))
|
||||
#endif
|
||||
{
|
||||
// Handle lists as PropertyDrawer is not called on the list itself.
|
||||
if (property.isArray)
|
||||
{
|
||||
var field = property.GetFieldInfo(out var _);
|
||||
var attribute = field?.GetCustomAttribute<Attributes.DecoratedProperty>();
|
||||
|
||||
if (field != null && attribute != null)
|
||||
{
|
||||
var id = GetPropertyIdentifier(property);
|
||||
|
||||
if (!_Lists.ContainsKey(id))
|
||||
{
|
||||
_Lists[id] = new DecoratedDrawer()
|
||||
{
|
||||
_Attribute = attribute,
|
||||
_Field = field,
|
||||
};
|
||||
}
|
||||
|
||||
DecoratedDrawer.s_IsList = true;
|
||||
var label = new GUIContent(property.displayName);
|
||||
_Lists[id].OnGUI(Rect.zero, property, label);
|
||||
DecoratedDrawer.s_IsList = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Only support top level ordering for now.
|
||||
EditorGUILayout.PropertyField(property, includeChildren: true);
|
||||
}
|
||||
@@ -189,18 +148,11 @@ namespace WaveHarmonic.Crest.Editor
|
||||
// Need to call just in case there is no decorated property.
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
OnChange();
|
||||
}
|
||||
|
||||
// Restore previous in case this is a nested editor.
|
||||
Current = previous;
|
||||
|
||||
// Fixes indented validation etc.
|
||||
EditorGUI.indentLevel = 0;
|
||||
|
||||
_UndoRedo = false;
|
||||
}
|
||||
|
||||
protected virtual void RenderBottomButtons()
|
||||
@@ -262,45 +214,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
}
|
||||
}
|
||||
|
||||
// Reflection
|
||||
partial class Inspector
|
||||
{
|
||||
static readonly PropertyInfo s_GUIViewCurrent = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.GUIView").GetProperty("current", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
static readonly PropertyInfo s_GUIViewNativeHandle = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.GUIView").GetProperty("nativeHandle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
|
||||
// Adapted from:
|
||||
// https://github.com/Unity-Technologies/UnityCsReference/blob/59b03b8a0f179c0b7e038178c90b6c80b340aa9f/Editor/Mono/Inspector/ReorderableListWrapper.cs#L77-L88
|
||||
static string GetPropertyIdentifier(SerializedProperty serializedProperty)
|
||||
{
|
||||
// Property may be disposed.
|
||||
try
|
||||
{
|
||||
var handle = -1;
|
||||
var current = s_GUIViewCurrent.GetValue(null);
|
||||
|
||||
if (current != null)
|
||||
{
|
||||
handle = ((IntPtr)s_GUIViewNativeHandle.GetValue(current)).ToInt32();
|
||||
}
|
||||
|
||||
return serializedProperty?.propertyPath + serializedProperty.serializedObject.targetObject.GetEntityId() + handle;
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
partial class Inspector
|
||||
{
|
||||
internal bool _UndoRedo;
|
||||
void OnUndoRedo()
|
||||
{
|
||||
_UndoRedo = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from:
|
||||
// https://gist.github.com/thebeardphantom/1ad9aee0ef8de6271fff39f1a6a3d66d
|
||||
static partial class Extensions
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor.Build;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WaveHarmonic.Crest.Editor.Reflected
|
||||
{
|
||||
static class BuildTargetGroup
|
||||
{
|
||||
public const int k_Server = -2;
|
||||
}
|
||||
|
||||
static class BuildPlatform
|
||||
{
|
||||
internal static readonly Type s_BuildPlatformType = Type.GetType("UnityEditor.Build.BuildPlatform,UnityEditor.CoreModule");
|
||||
internal static readonly Type s_BuildPlatformArrayType = s_BuildPlatformType.MakeArrayType();
|
||||
|
||||
static readonly FieldInfo s_NamedBuildTargetField = s_BuildPlatformType.GetField
|
||||
(
|
||||
"namedBuildTarget",
|
||||
BindingFlags.Instance | BindingFlags.Public
|
||||
);
|
||||
|
||||
public static NamedBuildTarget GetNamedBuildTarget(object platform)
|
||||
{
|
||||
return (NamedBuildTarget)s_NamedBuildTargetField.GetValue(platform);
|
||||
}
|
||||
}
|
||||
|
||||
static class BuildPlatforms
|
||||
{
|
||||
static readonly Type s_BuildPlatformsType = Type.GetType("UnityEditor.Build.BuildPlatforms,UnityEditor.CoreModule");
|
||||
static readonly PropertyInfo s_BuildPlatformsInstanceProperty = s_BuildPlatformsType.GetProperty("instance", BindingFlags.Static | BindingFlags.Public);
|
||||
static readonly MethodInfo s_GetValidPlatformsMethod = s_BuildPlatformsType.GetMethod("GetValidPlatforms", new Type[] { });
|
||||
static Array s_Platforms; // Should be safe to cache.
|
||||
|
||||
public static Array GetValidPlatforms()
|
||||
{
|
||||
if (s_Platforms == null)
|
||||
{
|
||||
var instance = s_BuildPlatformsInstanceProperty.GetValue(null);
|
||||
|
||||
// We cannot just cast to the type we want it seems.
|
||||
var enumerable = ((IEnumerable<object>)s_GetValidPlatformsMethod.Invoke(instance, null)).ToList();
|
||||
|
||||
s_Platforms = Array.CreateInstance(BuildPlatform.s_BuildPlatformType, enumerable.Count);
|
||||
|
||||
for (var i = 0; i < enumerable.Count; i++)
|
||||
{
|
||||
s_Platforms.SetValue(enumerable[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
return s_Platforms;
|
||||
}
|
||||
}
|
||||
|
||||
static class EditorGUILayout
|
||||
{
|
||||
static readonly MethodInfo s_BeginPlatformGroupingMethod = typeof(UnityEditor.EditorGUILayout).GetMethod
|
||||
(
|
||||
"BeginPlatformGrouping",
|
||||
BindingFlags.Static | BindingFlags.NonPublic,
|
||||
null,
|
||||
new Type[]
|
||||
{
|
||||
BuildPlatform.s_BuildPlatformArrayType,
|
||||
typeof(GUIContent),
|
||||
},
|
||||
null
|
||||
);
|
||||
|
||||
static readonly object[] s_Parameters = new object[2];
|
||||
|
||||
public static int BeginBuildTargetSelectionGrouping(GUIContent defaultTab)
|
||||
{
|
||||
var platforms = BuildPlatforms.GetValidPlatforms();
|
||||
|
||||
s_Parameters[0] = platforms;
|
||||
s_Parameters[1] = defaultTab;
|
||||
|
||||
var index = (int)s_BeginPlatformGroupingMethod.Invoke(null, s_Parameters);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
// Default
|
||||
return (int)UnityEditor.BuildTargetGroup.Unknown;
|
||||
}
|
||||
|
||||
var target = BuildPlatform.GetNamedBuildTarget(platforms.GetValue(index));
|
||||
|
||||
if (target == NamedBuildTarget.Server)
|
||||
{
|
||||
// Server
|
||||
return BuildTargetGroup.k_Server;
|
||||
}
|
||||
|
||||
return (int)target.ToBuildTargetGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd362a01f52cc4002857e9f549c641be
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -10,7 +10,7 @@ namespace WaveHarmonic.Crest.Editor.Settings
|
||||
{
|
||||
static class ScriptingSymbols
|
||||
{
|
||||
internal static NamedBuildTarget CurrentNamedBuildTarget
|
||||
static NamedBuildTarget CurrentNamedBuildTarget
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -10,10 +10,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
{
|
||||
abstract class TexturePreview : ObjectPreview
|
||||
{
|
||||
static readonly System.Reflection.MethodInfo s_DrawPreview = typeof(ObjectPreview).GetMethod("DrawPreview", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
|
||||
static readonly object[] s_DrawPreviewArguments = new object[3];
|
||||
static readonly Object[] s_DrawPreviewTargets = new Object[1];
|
||||
|
||||
public static TexturePreview s_ActiveInstance;
|
||||
public bool Open { get; private set; }
|
||||
|
||||
@@ -105,9 +101,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
Helpers.SafeCreateRenderTexture(ref _RenderTexture, descriptor);
|
||||
_RenderTexture.Create();
|
||||
Object.DestroyImmediate(_Editor);
|
||||
// Raises both, but no way to avoid it:
|
||||
// | The targets array should not be used inside OnSceneGUI or OnPreviewGUI. Use the single target property instead.
|
||||
// | The serializedObject should not be used inside OnSceneGUI or OnPreviewGUI. Use the target property directly instead.
|
||||
_Editor = UnityEditor.Editor.CreateEditor(_RenderTexture);
|
||||
// Reset for incompatible copy.
|
||||
descriptor = _OriginalDescriptor;
|
||||
@@ -128,13 +121,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
Graphics.CopyTexture(Texture, _RenderTexture);
|
||||
}
|
||||
|
||||
s_DrawPreviewTargets[0] = _Editor.target;
|
||||
s_DrawPreviewArguments[0] = _Editor;
|
||||
s_DrawPreviewArguments[1] = rect;
|
||||
s_DrawPreviewArguments[2] = s_DrawPreviewTargets;
|
||||
|
||||
// Use to be _Editor.DrawPreview(rect) but spammed errors with multiple selected.
|
||||
s_DrawPreview?.Invoke(null, s_DrawPreviewArguments);
|
||||
_Editor.DrawPreview(rect);
|
||||
}
|
||||
|
||||
#if CREST_DEBUG
|
||||
|
||||
@@ -9,7 +9,6 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using WaveHarmonic.Crest.Editor;
|
||||
using WaveHarmonic.Crest.Internal;
|
||||
|
||||
namespace WaveHarmonic.Crest.Editor
|
||||
@@ -55,9 +54,9 @@ namespace WaveHarmonic.Crest.Editor
|
||||
new(),
|
||||
};
|
||||
|
||||
public delegate void ShowMessage(string message, string fixDescription, MessageType type, Object @object = null, FixValidation action = null, string property = null, Object caller = null);
|
||||
public delegate void ShowMessage(string message, string fixDescription, MessageType type, Object @object = null, FixValidation action = null, string property = null);
|
||||
|
||||
public static void DebugLog(string message, string fixDescription, MessageType type, Object @object = null, FixValidation action = null, string property = null, Object caller = null)
|
||||
public static void DebugLog(string message, string fixDescription, MessageType type, Object @object = null, FixValidation action = null, string property = null)
|
||||
{
|
||||
// Never log info validation to console.
|
||||
if (type == MessageType.Info)
|
||||
@@ -65,27 +64,22 @@ namespace WaveHarmonic.Crest.Editor
|
||||
return;
|
||||
}
|
||||
|
||||
// Always link back to the caller so developers know the origin. They can always
|
||||
// use the help box "Inspect" once there to get to the object to fix. Even better,
|
||||
// they can use any available fix buttons too.
|
||||
var context = caller != null ? caller : @object;
|
||||
|
||||
message = $"<b>Crest Validation:</b> {message} {fixDescription} Click this message to highlight the problem object.";
|
||||
message = $"Crest Validation: {message} {fixDescription} Click this message to highlight the problem object.";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MessageType.Error: Debug.LogError(message, context); break;
|
||||
case MessageType.Warning: Debug.LogWarning(message, context); break;
|
||||
default: Debug.Log(message, context); break;
|
||||
case MessageType.Error: Debug.LogError(message, @object); break;
|
||||
case MessageType.Warning: Debug.LogWarning(message, @object); break;
|
||||
default: Debug.Log(message, @object); break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void HelpBox(string message, string fixDescription, MessageType type, Object @object = null, FixValidation action = null, string property = null, Object caller = null)
|
||||
public static void HelpBox(string message, string fixDescription, MessageType type, Object @object = null, FixValidation action = null, string property = null)
|
||||
{
|
||||
s_Messages[(int)type].Add(new() { _Message = message, _FixDescription = fixDescription, _Object = @object, _Action = action, _PropertyPath = property });
|
||||
}
|
||||
|
||||
public static void Suppressed(string _0, string _1, MessageType _2, Object _3 = null, FixValidation _4 = null, string _5 = null, Object _6 = null)
|
||||
public static void Suppressed(string _0, string _1, MessageType _2, Object _3 = null, FixValidation _4 = null, string _5 = null)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -297,24 +291,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Nested components do not descend from Object, but they could and this
|
||||
// would work for them.
|
||||
if (target is Object @object)
|
||||
{
|
||||
foreach (var field in TypeCache.GetFieldsWithAttribute<Validated>())
|
||||
{
|
||||
if (field.DeclaringType != type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var attribute in field.GetCustomAttributes<Validated>())
|
||||
{
|
||||
isValid &= attribute.Validate(@object, field, messenger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
@@ -323,89 +299,4 @@ namespace WaveHarmonic.Crest.Editor
|
||||
return ExecuteValidators(target, DebugLog);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Validated : System.Attribute
|
||||
{
|
||||
public abstract bool Validate(Object target, FieldInfo property, ValidatedHelper.ShowMessage messenger);
|
||||
}
|
||||
}
|
||||
|
||||
namespace WaveHarmonic.Crest
|
||||
{
|
||||
/// <summary>
|
||||
/// Validates that field is not null.
|
||||
/// </summary>
|
||||
[System.AttributeUsage(System.AttributeTargets.Field, AllowMultiple = false)]
|
||||
sealed class Required : Validated
|
||||
{
|
||||
public override bool Validate(Object target, FieldInfo field, ValidatedHelper.ShowMessage messenger)
|
||||
{
|
||||
var isValid = true;
|
||||
|
||||
if ((Object)field.GetValue(target) == null)
|
||||
{
|
||||
var typeName = EditorHelpers.Pretty(target.GetType().Name);
|
||||
var fieldName = EditorHelpers.Pretty(field.Name);
|
||||
|
||||
messenger
|
||||
(
|
||||
$"<i>{fieldName}</i> is required for the <i>{typeName}</i> component to function.",
|
||||
$"Please set <i>{fieldName}</i>.",
|
||||
ValidatedHelper.MessageType.Error,
|
||||
target
|
||||
);
|
||||
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows a info message if field is null.
|
||||
/// </summary>
|
||||
[System.AttributeUsage(System.AttributeTargets.Field, AllowMultiple = false)]
|
||||
sealed class Optional : Validated
|
||||
{
|
||||
readonly string _Message;
|
||||
|
||||
public Optional(string message)
|
||||
{
|
||||
_Message = message;
|
||||
}
|
||||
|
||||
public override bool Validate(Object target, FieldInfo field, ValidatedHelper.ShowMessage messenger)
|
||||
{
|
||||
var value = field.GetValue(target);
|
||||
|
||||
if (value is ICollection<Object> list)
|
||||
{
|
||||
if (list != null && list.Count > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is Object @object && @object != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var typeName = EditorHelpers.Pretty(target.GetType().Name);
|
||||
var fieldName = EditorHelpers.Pretty(field.Name);
|
||||
|
||||
messenger
|
||||
(
|
||||
$"<i>{fieldName}</i> is not set for the <i>{typeName}</i> component. " + _Message,
|
||||
string.Empty,
|
||||
ValidatedHelper.MessageType.Info,
|
||||
target
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.HighDefinition;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
using WaveHarmonic.Crest.Editor.Settings;
|
||||
using WaveHarmonic.Crest.Internal;
|
||||
using WaveHarmonic.Crest.Watercraft;
|
||||
|
||||
@@ -21,9 +20,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
{
|
||||
// HDRP sub-shader always first.
|
||||
const int k_SubShaderIndexHDRP = 0;
|
||||
const string k_NoneQueryProviderCollisionFloatingObjects = "The floating objects in the scene will use a flat horizontal plane.";
|
||||
const string k_NoneQueryProviderFlowFloatingObjects = "The floating objects in the scene will not receive motion from flow.";
|
||||
|
||||
internal static WaterRenderer Water => Utility.Water;
|
||||
static readonly System.Collections.Generic.List<Terrain> s_Terrains = new();
|
||||
static readonly ShaderTagId s_RenderPipelineShaderTagID = new("RenderPipeline");
|
||||
@@ -257,6 +253,18 @@ namespace WaveHarmonic.Crest.Editor
|
||||
return isValid;
|
||||
}
|
||||
|
||||
#if !d_Crest_LegacyUnderwater
|
||||
if (target.AllCameras)
|
||||
{
|
||||
messenger
|
||||
(
|
||||
"<i>All Cameras</i> requires <i>Legacy Underwater</i> to be enabled.",
|
||||
"Either disable <i>All Cameras</i> or enable <i>Project Settings > Crest > Legacy Underwater</i>.",
|
||||
MessageType.Warning, water
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (target.Material != null)
|
||||
{
|
||||
var material = target.Material;
|
||||
@@ -546,7 +554,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
{
|
||||
foreach (var simulation in target.Simulations)
|
||||
{
|
||||
ValidateSimulationAndMaterial(OptionalLod.Get(simulation.GetType()), messenger, water, target);
|
||||
ValidateSimulationAndMaterial(OptionalLod.Get(simulation.GetType()), messenger, water);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -560,7 +568,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
);
|
||||
}
|
||||
|
||||
if (target.Viewer == null && !target.IsRunningWithoutGraphics && !target.MultipleViewpoints)
|
||||
if (target.Viewer == null && !target.IsRunningWithoutGraphics)
|
||||
{
|
||||
messenger
|
||||
(
|
||||
@@ -719,7 +727,8 @@ namespace WaveHarmonic.Crest.Editor
|
||||
if (target.Clipped && water != null)
|
||||
{
|
||||
// Validate main material, then overriden material.
|
||||
ValidateLod(OptionalLod.Get(typeof(ClipLod)), messenger, water, material: target._Material, context: target);
|
||||
ValidateLod(OptionalLod.Get(typeof(ClipLod)), messenger, water);
|
||||
ValidateLod(OptionalLod.Get(typeof(ClipLod)), messenger, water, material: target._Material);
|
||||
|
||||
if (water.ClipLod.DefaultClippingState == DefaultClippingState.NothingClipped)
|
||||
{
|
||||
@@ -729,8 +738,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
$"The {nameof(WaterBody.Clipped)} option will have no effect.",
|
||||
$"Disable {nameof(WaterBody.Clipped)} or set {nameof(ClipLod.DefaultClippingState)} to {DefaultClippingState.NothingClipped}.",
|
||||
MessageType.Warning,
|
||||
water,
|
||||
caller: target
|
||||
water
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -751,8 +759,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
return isValid;
|
||||
}
|
||||
|
||||
isValid &= ValidateProjectSettings(target, water, messenger, context);
|
||||
|
||||
var simulation = target.GetLod(water);
|
||||
|
||||
var dependentClause = ".";
|
||||
@@ -781,8 +787,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
simulation._Enabled = false;
|
||||
}
|
||||
},
|
||||
$"{target.PropertyName}.{nameof(Lod._Enabled)}",
|
||||
context
|
||||
$"{target.PropertyName}.{nameof(Lod._Enabled)}"
|
||||
);
|
||||
|
||||
isValid = false;
|
||||
@@ -797,20 +802,20 @@ namespace WaveHarmonic.Crest.Editor
|
||||
{
|
||||
if (material.HasProperty(target.MaterialProperty) && material.GetFloat(target.MaterialProperty) != 1f)
|
||||
{
|
||||
ShowMaterialValidationMessage(target, material, messenger, context);
|
||||
ShowMaterialValidationMessage(target, material, messenger);
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (target.Dependency != null)
|
||||
{
|
||||
ValidateLod(OptionalLod.Get(target.Dependency), messenger, water, dependent, context: context);
|
||||
ValidateLod(OptionalLod.Get(target.Dependency), messenger, water, dependent);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
static bool ValidateSignedDistanceFieldsLod(ShowMessage messenger, WaterRenderer water, string feature, Object context)
|
||||
static bool ValidateSignedDistanceFieldsLod(ShowMessage messenger, WaterRenderer water, string feature)
|
||||
{
|
||||
var isValid = true;
|
||||
|
||||
@@ -822,8 +827,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
"Enable <i>Signed Distance Fields</i>",
|
||||
MessageType.Error, water,
|
||||
(_, y) => y.boolValue = true,
|
||||
$"{nameof(WaterRenderer._DepthLod)}.{nameof(DepthLod._EnableSignedDistanceFields)}",
|
||||
caller: context
|
||||
$"{nameof(WaterRenderer._DepthLod)}.{nameof(DepthLod._EnableSignedDistanceFields)}"
|
||||
);
|
||||
|
||||
isValid = false;
|
||||
@@ -832,7 +836,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
return isValid;
|
||||
}
|
||||
|
||||
static void ShowMaterialValidationMessage(OptionalLod target, Material material, ShowMessage messenger, Object caller)
|
||||
static void ShowMaterialValidationMessage(OptionalLod target, Material material, ShowMessage messenger)
|
||||
{
|
||||
messenger
|
||||
(
|
||||
@@ -843,43 +847,13 @@ namespace WaveHarmonic.Crest.Editor
|
||||
);
|
||||
}
|
||||
|
||||
static bool ValidateProjectSettings(OptionalLod target, WaterRenderer water, ShowMessage messenger, Object caller)
|
||||
{
|
||||
var isValid = true;
|
||||
|
||||
var lod = target.GetLod(water);
|
||||
|
||||
if (lod._Enabled && !target.GetProjectSettingToggle())
|
||||
{
|
||||
var platform = ScriptingSymbols.CurrentNamedBuildTarget;
|
||||
|
||||
messenger
|
||||
(
|
||||
$"<i>{target.PropertyLabel}</i> must be enabled for this platform in the project settings.",
|
||||
$"Enable <i>Project Settings > Crest > Features > Default/{platform.TargetName} > {target.PropertyLabel}</i>. " +
|
||||
$"It will be in either Default or {platform.TargetName}",
|
||||
MessageType.Error, ProjectSettings.Instance,
|
||||
caller: caller
|
||||
);
|
||||
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
static bool ValidateSimulationAndMaterial(OptionalLod target, ShowMessage messenger, WaterRenderer water, Object caller)
|
||||
static bool ValidateSimulationAndMaterial(OptionalLod target, ShowMessage messenger, WaterRenderer water)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ValidateProjectSettings(target, water, messenger, caller))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!target.HasMaterialToggle)
|
||||
{
|
||||
return true;
|
||||
@@ -901,7 +875,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
|
||||
if (feature._Enabled)
|
||||
{
|
||||
ShowMaterialValidationMessage(target, water.Surface.Material, messenger, caller);
|
||||
ShowMaterialValidationMessage(target, water.Surface.Material, messenger);
|
||||
}
|
||||
else if (messenger != DebugLog)
|
||||
{
|
||||
@@ -929,8 +903,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
(
|
||||
$"The wave spectrum is limited by the <i>Global Wind Speed</i> on the <i>Water Renderer</i> to {water.WindSpeedKPH} KPH.",
|
||||
$"If you want fully developed waves, either override the wind speed on this component or increase the <i>Global Wind Speed</i>.",
|
||||
MessageType.Info,
|
||||
caller: target
|
||||
MessageType.Info
|
||||
);
|
||||
}
|
||||
|
||||
@@ -948,7 +921,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
|
||||
if (Water != null)
|
||||
{
|
||||
isValid &= ValidateLod(OptionalLod.Get(typeof(AnimatedWavesLod)), messenger, Water, context: target);
|
||||
isValid &= ValidateLod(OptionalLod.Get(typeof(AnimatedWavesLod)), messenger, Water);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
@@ -962,7 +935,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
// Validate require water feature.
|
||||
if (Water != null)
|
||||
{
|
||||
isValid &= ValidateLod(OptionalLod.Get(typeof(DynamicWavesLod)), messenger, Water, context: target);
|
||||
isValid &= ValidateLod(OptionalLod.Get(typeof(DynamicWavesLod)), messenger, Water);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
@@ -976,19 +949,19 @@ namespace WaveHarmonic.Crest.Editor
|
||||
// Validate require water feature.
|
||||
if (Water != null)
|
||||
{
|
||||
isValid &= !target.UsesClip || ValidateLod(OptionalLod.Get(typeof(ClipLod)), messenger, Water, context: target);
|
||||
isValid &= !target.UsesDisplacement || ValidateLod(OptionalLod.Get(typeof(AnimatedWavesLod)), messenger, Water, context: target);
|
||||
isValid &= !target.UsesClip || ValidateLod(OptionalLod.Get(typeof(ClipLod)), messenger, Water);
|
||||
isValid &= !target.UsesDisplacement || ValidateLod(OptionalLod.Get(typeof(AnimatedWavesLod)), messenger, Water);
|
||||
isValid &= !target.UsesDisplacement || ValidateCollisionLayer(CollisionLayer.AfterDynamicWaves, target, messenger, "mode", target.Mode, required: true);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
internal static void FixSetQuerySourceToCompute(SerializedObject _, SerializedProperty property)
|
||||
internal static void FixSetCollisionSourceToCompute(SerializedObject _, SerializedProperty property)
|
||||
{
|
||||
if (Water != null)
|
||||
{
|
||||
property.enumValueIndex = (int)LodQuerySource.GPU;
|
||||
property.enumValueIndex = (int)CollisionSource.GPU;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1005,8 +978,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
}
|
||||
|
||||
isValid &= ValidateCollisionLayer(target.Layer, target, messenger, "layer", target.Layer, required: false);
|
||||
isValid &= ValidateQuerySource(target, messenger, Water.AnimatedWavesLod, k_NoneQueryProviderCollisionFloatingObjects);
|
||||
isValid &= ValidateQuerySource(target, messenger, Water.FlowLod, k_NoneQueryProviderFlowFloatingObjects);
|
||||
isValid &= ValidateCollisionSource(target, messenger);
|
||||
|
||||
return isValid;
|
||||
}
|
||||
@@ -1022,8 +994,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
}
|
||||
|
||||
isValid &= ValidateCollisionLayer(target._Layer, target, messenger, "layer", target._Layer, required: false);
|
||||
isValid &= ValidateQuerySource(target, messenger, Water.AnimatedWavesLod, k_NoneQueryProviderCollisionFloatingObjects);
|
||||
isValid &= ValidateQuerySource(target, messenger, Water.FlowLod, k_NoneQueryProviderFlowFloatingObjects);
|
||||
isValid &= ValidateCollisionSource(target, messenger);
|
||||
|
||||
return isValid;
|
||||
}
|
||||
@@ -1168,31 +1139,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
// Validate that any water feature required for this input is enabled, if any
|
||||
if (Water != null)
|
||||
{
|
||||
isValid &= ValidateLod(OptionalLod.Get(target.GetType()), messenger, Water, context: target);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
[Validator(typeof(LevelLodInput))]
|
||||
static bool ValidateLevelLodInput(LevelLodInput target, ShowMessage messenger)
|
||||
{
|
||||
var isValid = true;
|
||||
|
||||
if (target.Mode is LodInputMode.Geometry or LodInputMode.Spline)
|
||||
{
|
||||
if (target.Blend is LodInputBlend.Minimum or LodInputBlend.Maximum && target.Weight < 1f)
|
||||
{
|
||||
messenger
|
||||
(
|
||||
"Weight with minimum or maximum blend modes do not always behave correctly. " +
|
||||
"Any weight less than one will move the value in the simulation towards zero, rather than towards the existing value in the simulation. " +
|
||||
"For example, this input with a zero weight, and with a blend mode set to maximum, will replace any negative water level instead of not doing anything.",
|
||||
"", // Nothing to suggest yet, as in cases this is still valid.
|
||||
MessageType.Warning,
|
||||
target
|
||||
);
|
||||
}
|
||||
isValid &= ValidateLod(OptionalLod.Get(target.GetType()), messenger, Water);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
@@ -1365,8 +1312,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
$"This can cause the <i>{nameof(DepthProbe)}</i> not to work. " +
|
||||
$"Unity fixed this in 2022.3.23f1.",
|
||||
$"If you are experiencing problems, disable depth priming or upgrade Unity.",
|
||||
MessageType.Info, urpRenderer,
|
||||
caller: target
|
||||
MessageType.Info, urpRenderer
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1380,8 +1326,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
$"This can cause the <i>{nameof(DepthProbe)}</i> not to work. " +
|
||||
$"Unity fixed this in 2022.3.23f1.",
|
||||
$"If you are experiencing problems, disable SSAO or upgrade Unity.",
|
||||
MessageType.Info, urpRenderer,
|
||||
caller: target
|
||||
MessageType.Info, urpRenderer
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1404,8 +1349,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
"It is not expected that a depth probe object has a Renderer component in its hierarchy." +
|
||||
"The probe is typically attached to an empty GameObject. Please refer to the example content.",
|
||||
"Remove the Renderer component from this object or its children.",
|
||||
MessageType.Warning, renderer,
|
||||
caller: target
|
||||
MessageType.Warning, renderer
|
||||
);
|
||||
|
||||
// Reporting only one renderer at a time will be enough to avoid overwhelming user and UI.
|
||||
@@ -1420,11 +1364,11 @@ namespace WaveHarmonic.Crest.Editor
|
||||
// Validate require water feature.
|
||||
if (water != null)
|
||||
{
|
||||
isValid = isValid && ValidateLod(OptionalLod.Get(typeof(DepthLod)), messenger, water, context: target);
|
||||
isValid = isValid && ValidateLod(OptionalLod.Get(typeof(DepthLod)), messenger, water);
|
||||
|
||||
if (!water._DepthLod._EnableSignedDistanceFields && target._GenerateSignedDistanceField)
|
||||
{
|
||||
isValid = isValid && ValidateSignedDistanceFieldsLod(messenger, water, "Generate Signed Distance Field", target);
|
||||
isValid = isValid && ValidateSignedDistanceFieldsLod(messenger, water, "Generate Signed Distance Field");
|
||||
}
|
||||
|
||||
if (water.DepthLod.IncludeTerrainHeight && Object.FindAnyObjectByType<Terrain>(FindObjectsInactive.Include) != null)
|
||||
@@ -1436,8 +1380,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
"But typically, if you are using a DepthProbe, it is best to capture the terrain too, as it is more accurate. " +
|
||||
"One reason to use a DepthProbe together with the auto capture is for better real-time/on-demand depth capture performance.",
|
||||
string.Empty,
|
||||
MessageType.Info, water,
|
||||
caller: target
|
||||
MessageType.Info, water
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1454,15 +1397,14 @@ namespace WaveHarmonic.Crest.Editor
|
||||
|
||||
if (!target._DistanceFromEdge.IsEmpty())
|
||||
{
|
||||
isValid = isValid && ValidateLod(OptionalLod.Get(typeof(DepthLod)), messenger, water, context: target);
|
||||
isValid = isValid && ValidateSignedDistanceFieldsLod(messenger, water, "Distance From Edge", target);
|
||||
isValid = isValid && ValidateLod(OptionalLod.Get(typeof(DepthLod)), messenger, water);
|
||||
isValid = isValid && ValidateSignedDistanceFieldsLod(messenger, water, "Distance From Edge");
|
||||
}
|
||||
|
||||
if (!target._DistanceFromSurface.IsEmpty())
|
||||
{
|
||||
isValid &= ValidateCollisionLayer(target._Layer, target, messenger, "layer", target._Layer, required: false);
|
||||
isValid &= ValidateQuerySource(target, messenger, Water.AnimatedWavesLod, k_NoneQueryProviderCollisionFloatingObjects);
|
||||
isValid &= ValidateQuerySource(target, messenger, Water.FlowLod, k_NoneQueryProviderFlowFloatingObjects);
|
||||
isValid &= ValidateCollisionSource(target, messenger);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
@@ -1517,29 +1459,34 @@ namespace WaveHarmonic.Crest.Editor
|
||||
var isValid = true;
|
||||
|
||||
#if !d_CrestCPUQueries
|
||||
if (target.QuerySource == LodQuerySource.CPU)
|
||||
if (target.CollisionSource == CollisionSource.CPU)
|
||||
{
|
||||
messenger
|
||||
(
|
||||
"Collision Source is set to CPU but the <i>CPU Queries</i> package is not installed.",
|
||||
"Install the <i>CPU Queries</i> package or switch to GPU queries.",
|
||||
MessageType.Warning, target.Water,
|
||||
FixSetQuerySourceToCompute
|
||||
FixSetCollisionSourceToCompute
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
isValid &= ValidateQuerySource(target.Water, messenger, target, k_NoneQueryProviderCollisionFloatingObjects);
|
||||
if (target.CollisionSource == CollisionSource.None)
|
||||
{
|
||||
messenger
|
||||
(
|
||||
"Collision Source in Water Renderer is set to None. The floating objects in the scene will use a flat horizontal plane.",
|
||||
"Set collision source to GPU.",
|
||||
MessageType.Warning, target.Water,
|
||||
FixSetCollisionSourceToCompute,
|
||||
$"{nameof(WaterRenderer._AnimatedWavesLod)}.{nameof(AnimatedWavesLod._CollisionSource)}"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
[Validator(typeof(FlowLod))]
|
||||
static bool Validate(FlowLod target, ShowMessage messenger)
|
||||
{
|
||||
return ValidateQuerySource(target.Water, messenger, target, k_NoneQueryProviderFlowFloatingObjects);
|
||||
}
|
||||
|
||||
[Validator(typeof(ScatteringLod))]
|
||||
static bool Validate(ScatteringLod target, ShowMessage messenger)
|
||||
{
|
||||
@@ -1592,8 +1539,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
messenger
|
||||
(
|
||||
$"No water present. {nameof(CutsceneTimeProvider)} will have no effect.",
|
||||
"", MessageType.Warning,
|
||||
caller: target
|
||||
"", MessageType.Warning
|
||||
);
|
||||
|
||||
isValid = false;
|
||||
@@ -1606,8 +1552,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
(
|
||||
$"No {nameof(UnityEngine.Playables.PlayableDirector)} component assigned. {nameof(CutsceneTimeProvider)} will have no effect.",
|
||||
$"Add a {nameof(UnityEngine.Playables.PlayableDirector)}",
|
||||
MessageType.Error,
|
||||
caller: target
|
||||
MessageType.Error
|
||||
);
|
||||
|
||||
isValid = false;
|
||||
@@ -1617,8 +1562,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
(
|
||||
$"This component requires the com.unity.modules.director built-in module to function.",
|
||||
$"Enable the com.unity.modules.director built-in module.",
|
||||
MessageType.Error,
|
||||
caller: target
|
||||
MessageType.Error
|
||||
);
|
||||
|
||||
isValid = false;
|
||||
@@ -1681,8 +1625,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
(
|
||||
$"{typeof(T).Name} requires a {typeof(C).Name} to be set or present on same object.",
|
||||
$"Set the {typeof(C).Name} property or add a {typeof(C).Name}.",
|
||||
MessageType.Error,
|
||||
caller: target
|
||||
MessageType.Error
|
||||
);
|
||||
|
||||
isValid = false;
|
||||
@@ -1716,10 +1659,9 @@ namespace WaveHarmonic.Crest.Editor
|
||||
(
|
||||
$"The {value} {label} requires the {flag} layer which is not enabled.",
|
||||
fix,
|
||||
required ? MessageType.Error : MessageType.Warning, Water,
|
||||
required ? MessageType.Error : MessageType.Warning, messenger == DebugLog ? target : Water,
|
||||
(_, y) => y.intValue = (int)(layers | flag),
|
||||
$"{nameof(WaterRenderer._AnimatedWavesLod)}.{nameof(WaterRenderer._AnimatedWavesLod._CollisionLayers)}",
|
||||
caller: target
|
||||
$"{nameof(WaterRenderer._AnimatedWavesLod)}.{nameof(WaterRenderer._AnimatedWavesLod._CollisionLayers)}"
|
||||
);
|
||||
|
||||
return !required;
|
||||
@@ -1728,28 +1670,21 @@ namespace WaveHarmonic.Crest.Editor
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ValidateQuerySource(Object target, ShowMessage messenger, IQueryableLod<IQueryProvider> lod, string extra)
|
||||
static bool ValidateCollisionSource(Object target, ShowMessage messenger)
|
||||
{
|
||||
if (Water == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!lod.Enabled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lod.QuerySource == LodQuerySource.None)
|
||||
if (Water._AnimatedWavesLod.CollisionSource == CollisionSource.None)
|
||||
{
|
||||
messenger
|
||||
(
|
||||
$"<i>{nameof(WaterRenderer)} > {lod.Name} > {nameof(lod.QuerySource)}</i> is set to <i>None</i>. {extra}",
|
||||
$"Set the <i>{nameof(lod.QuerySource)}</i> to <i>{nameof(LodQuerySource.GPU)}</i> to use data.",
|
||||
MessageType.Info, Water,
|
||||
FixSetQuerySourceToCompute,
|
||||
$"_{lod.GetType().Name}._{nameof(lod.QuerySource)}",
|
||||
caller: target
|
||||
"<i>Collision Source</i> on the <i>Water Renderer</i> is set to <i>None</i>. The floating objects in the scene will use a flat horizontal plane.",
|
||||
"Set the <i>Collision Source</i> to <i>GPU</i> to incorporate waves into physics.",
|
||||
MessageType.Warning, Water,
|
||||
FixSetCollisionSourceToCompute
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user