Skip to content

Commit f37546b

Browse files
alex-vazquezsebastienlagarde
authored andcommitted
[HDRP]Improvements and fixes on Volumes Components Inspectors #3072
1 parent a97fda5 commit f37546b

File tree

23 files changed

+388
-28
lines changed

23 files changed

+388
-28
lines changed

com.unity.render-pipelines.core/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99
### Fixed
1010
- Fixed the default background color for previews to use the original color.
1111
- Fixed a bug in FreeCamera which would only provide a speed boost for the first frame when pressing the Shfit key.
12+
- Fixed spacing between property fields on the Volume Component Editors.
13+
- Fixed ALL/NONE to maintain the state on the Volume Component Editors.
14+
- Fixed the selection of the Additional properties from ALL/NONE when the option "Show additional properties" is disabled
15+
- Fixed ACES tonemaping for Nintendo Switch by forcing some shader color conversion functions to full float precision.
1216

1317
## [10.2.0] - 2020-10-19
1418

com.unity.render-pipelines.core/Editor/Volume/VolumeComponentEditor.cs

Lines changed: 92 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,26 @@ public VolumeComponentEditorAttribute(Type componentType)
7575
/// <seealso cref="VolumeComponentEditorAttribute"/>
7676
public class VolumeComponentEditor
7777
{
78+
class Styles
79+
{
80+
public static GUIContent overrideSettingText { get; } = EditorGUIUtility.TrTextContent("", "Override this setting for this volume.");
81+
public static GUIContent allText { get; } = EditorGUIUtility.TrTextContent("ALL", "Toggle all overrides on. To maximize performances you should only toggle overrides that you actually need.");
82+
public static GUIContent noneText { get; } = EditorGUIUtility.TrTextContent("NONE", "Toggle all overrides off.");
83+
84+
public static string toggleAllText { get; } = L10n.Tr("Toggle All");
85+
}
86+
87+
Vector2? m_OverrideToggleSize;
88+
internal Vector2 overrideToggleSize
89+
{
90+
get
91+
{
92+
if (!m_OverrideToggleSize.HasValue)
93+
m_OverrideToggleSize = CoreEditorStyles.smallTickbox.CalcSize(Styles.overrideSettingText);
94+
return m_OverrideToggleSize.Value;
95+
}
96+
}
97+
7898
/// <summary>
7999
/// Specifies the <see cref="VolumeComponent"/> this editor is drawing.
80100
/// </summary>
@@ -99,10 +119,11 @@ public class VolumeComponentEditor
99119

100120
SerializedProperty m_AdvancedMode;
101121

122+
List<VolumeParameter> m_VolumeNotAdditionalParameters;
102123
/// <summary>
103124
/// Override this property if your editor makes use of the "More Options" feature.
104125
/// </summary>
105-
public virtual bool hasAdvancedMode => false;
126+
public virtual bool hasAdvancedMode => target.parameters.Count != m_VolumeNotAdditionalParameters.Count;
106127

107128
/// <summary>
108129
/// Checks if the editor currently has the "More Options" feature toggled on.
@@ -176,9 +197,18 @@ internal void Init(VolumeComponent target, Editor inspector)
176197
serializedObject = new SerializedObject(target);
177198
activeProperty = serializedObject.FindProperty("active");
178199
m_AdvancedMode = serializedObject.FindProperty("m_AdvancedMode");
200+
201+
InitParameters();
202+
179203
OnEnable();
180204
}
181205

206+
void InitParameters()
207+
{
208+
m_VolumeNotAdditionalParameters = new List<VolumeParameter>();
209+
VolumeComponent.FindParameters(target, m_VolumeNotAdditionalParameters, field => field.GetCustomAttribute<AdditionalPropertyAttribute>() == null);
210+
}
211+
182212
void GetFields(object o, List<(FieldInfo, SerializedProperty)> infos, SerializedProperty prop = null)
183213
{
184214
if (o == null)
@@ -281,21 +311,68 @@ public virtual string GetDisplayTitle()
281311
return target.displayName == "" ? ObjectNames.NicifyVariableName(target.GetType().Name) : target.displayName;
282312
}
283313

314+
void AddToogleState(GUIContent content, bool state)
315+
{
316+
bool allOverridesSameState = AreOverridesTo(state);
317+
if (GUILayout.Toggle(allOverridesSameState, content, CoreEditorStyles.miniLabelButton, GUILayout.ExpandWidth(false)) && !allOverridesSameState)
318+
SetOverridesTo(state);
319+
}
320+
284321
void TopRowFields()
285322
{
286323
using (new EditorGUILayout.HorizontalScope())
287324
{
288-
if (GUILayout.Button(EditorGUIUtility.TrTextContent("All", "Toggle all overrides on. To maximize performances you should only toggle overrides that you actually need."), CoreEditorStyles.miniLabelButton, GUILayout.Width(17f), GUILayout.ExpandWidth(false)))
289-
SetAllOverridesTo(true);
325+
AddToogleState(Styles.allText, true);
326+
AddToogleState(Styles.noneText, false);
327+
}
328+
}
329+
330+
/// <summary>
331+
/// Checks if all the visible parameters have the given state
332+
/// </summary>
333+
/// <param name="state">The state to check</param>
334+
internal bool AreOverridesTo(bool state)
335+
{
336+
if (hasAdvancedMode && isInAdvancedMode)
337+
return AreAllOverridesTo(state);
338+
339+
for (int i = 0; i < m_VolumeNotAdditionalParameters.Count; ++i)
340+
{
341+
if (m_VolumeNotAdditionalParameters[i].overrideState != state)
342+
return false;
343+
}
344+
return true;
345+
}
290346

291-
if (GUILayout.Button(EditorGUIUtility.TrTextContent("None", "Toggle all overrides off."), CoreEditorStyles.miniLabelButton, GUILayout.Width(32f), GUILayout.ExpandWidth(false)))
292-
SetAllOverridesTo(false);
347+
/// <summary>
348+
/// Sets the given state to all the visible parameters
349+
/// </summary>
350+
/// <param name="state">The state to check</param>
351+
internal void SetOverridesTo(bool state)
352+
{
353+
if (hasAdvancedMode && isInAdvancedMode)
354+
SetAllOverridesTo(state);
355+
else
356+
{
357+
Undo.RecordObject(target, Styles.toggleAllText);
358+
target.SetOverridesTo(m_VolumeNotAdditionalParameters, state);
359+
serializedObject.Update();
293360
}
294361
}
295362

363+
internal bool AreAllOverridesTo(bool state)
364+
{
365+
for (int i = 0; i < target.parameters.Count; ++i)
366+
{
367+
if (target.parameters[i].overrideState != state)
368+
return false;
369+
}
370+
return true;
371+
}
372+
296373
internal void SetAllOverridesTo(bool state)
297374
{
298-
Undo.RecordObject(target, "Toggle All");
375+
Undo.RecordObject(target, Styles.toggleAllText);
299376
target.SetAllOverridesTo(state);
300377
serializedObject.Update();
301378
}
@@ -423,9 +500,15 @@ protected void PropertyField(SerializedDataParameter property, GUIContent title)
423500
/// <param name="property">The property to draw the override checkbox for</param>
424501
protected void DrawOverrideCheckbox(SerializedDataParameter property)
425502
{
426-
var overrideRect = GUILayoutUtility.GetRect(17f, 17f, GUILayout.ExpandWidth(false));
427-
overrideRect.yMin += 4f;
428-
property.overrideState.boolValue = GUI.Toggle(overrideRect, property.overrideState.boolValue, EditorGUIUtility.TrTextContent("", "Override this setting for this volume."), CoreEditorStyles.smallTickbox);
503+
// Create a rect the height + vspacing of the property that is being overriden
504+
float height = EditorGUI.GetPropertyHeight(property.value) + EditorGUIUtility.standardVerticalSpacing;
505+
var overrideRect = GUILayoutUtility.GetRect(Styles.allText, CoreEditorStyles.miniLabelButton, GUILayout.Height(height), GUILayout.ExpandWidth(false));
506+
507+
// also center vertically the checkbox
508+
overrideRect.yMin += height * 0.5f - overrideToggleSize.y * 0.5f;
509+
overrideRect.xMin += overrideToggleSize.x * 0.5f;
510+
511+
property.overrideState.boolValue = GUI.Toggle(overrideRect, property.overrideState.boolValue, Styles.overrideSettingText, CoreEditorStyles.smallTickbox);
429512
}
430513
}
431514
}

com.unity.render-pipelines.core/Runtime/Common/CoreAttributes.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,12 @@ public class DisplayInfoAttribute : Attribute
1313
/// <summary>Display order used in UI.</summary>
1414
public int order;
1515
}
16+
17+
/// <summary>
18+
/// Attribute used to customize UI display to allow properties only be visible when "Show Additional Properties" is selected
19+
/// </summary>
20+
[AttributeUsage(AttributeTargets.Field)]
21+
public class AdditionalPropertyAttribute : Attribute
22+
{
23+
}
1624
}

com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,10 @@ public class VolumeComponent : ScriptableObject
8181
/// <summary>
8282
/// Extracts all the <see cref="VolumeParameter"/>s defined in this class and nested classes.
8383
/// </summary>
84-
static void GetParameters(object o, List<VolumeParameter> parameters)
84+
/// <param name="o">The object to find the parameters</param>
85+
/// <param name="parameters">The list filled with the parameters.</param>
86+
/// <param name="filter">If you want to filter the parameters</param>
87+
internal static void FindParameters(object o, List<VolumeParameter> parameters, Func<FieldInfo, bool> filter = null)
8588
{
8689
if (o == null)
8790
return;
@@ -93,9 +96,12 @@ static void GetParameters(object o, List<VolumeParameter> parameters)
9396
foreach (var field in fields)
9497
{
9598
if (field.FieldType.IsSubclassOf(typeof(VolumeParameter)))
96-
parameters.Add((VolumeParameter)field.GetValue(o));
99+
{
100+
if (filter?.Invoke(field) ?? true)
101+
parameters.Add((VolumeParameter)field.GetValue(o));
102+
}
97103
else if (!field.FieldType.IsArray && field.FieldType.IsClass)
98-
GetParameters(field.GetValue(o), parameters);
104+
FindParameters(field.GetValue(o), parameters, filter);
99105
}
100106
}
101107

@@ -109,7 +115,7 @@ protected virtual void OnEnable()
109115
{
110116
// Automatically grab all fields of type VolumeParameter for this instance
111117
var fields = new List<VolumeParameter>();
112-
GetParameters(this, fields);
118+
FindParameters(this, fields);
113119
parameters = fields.AsReadOnly();
114120

115121
foreach (var parameter in parameters)
@@ -195,10 +201,14 @@ public virtual void Override(VolumeComponent state, float interpFactor)
195201
/// <param name="state">The value to set the state of the overrides to.</param>
196202
public void SetAllOverridesTo(bool state)
197203
{
198-
SetAllOverridesTo(parameters, state);
204+
SetOverridesTo(parameters, state);
199205
}
200206

201-
void SetAllOverridesTo(IEnumerable<VolumeParameter> enumerable, bool state)
207+
/// <summary>
208+
/// Sets the override state of the given parameters on this component to a given value.
209+
/// </summary>
210+
/// <param name="state">The value to set the state of the overrides to.</param>
211+
internal void SetOverridesTo(IEnumerable<VolumeParameter> enumerable, bool state)
202212
{
203213
foreach (var prop in enumerable)
204214
{
@@ -213,7 +223,7 @@ void SetAllOverridesTo(IEnumerable<VolumeParameter> enumerable, bool state)
213223
.GetValue(prop, null);
214224

215225
if (innerParams != null)
216-
SetAllOverridesTo(innerParams, state);
226+
SetOverridesTo(innerParams, state);
217227
}
218228
}
219229
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using NUnit.Framework;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Reflection;
6+
7+
namespace UnityEngine.Rendering.Tests
8+
{
9+
public static class ReflectionUtils
10+
{
11+
/// <summary>
12+
/// Calls a private method from a class
13+
/// </summary>
14+
/// <param name="methodName">The method name</param>
15+
/// <param name="args">The arguments to pass to the method</param>
16+
public static object Invoke(this object target, string methodName, params object[] args)
17+
{
18+
Assert.True(target != null, "The target could not be null");
19+
Assert.IsNotEmpty(methodName, "The field to set could not be null");
20+
21+
var mi = target.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
22+
Assert.True(mi != null, $"Could not find method `{methodName}` on object `{target}`");
23+
return mi.Invoke(target, args);
24+
}
25+
26+
private static FieldInfo FindField(this Type type, string fieldName)
27+
{
28+
FieldInfo fi = null;
29+
30+
while (type != null)
31+
{
32+
fi = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
33+
34+
if (fi != null) break;
35+
36+
type = type.BaseType;
37+
}
38+
39+
Assert.True(fi != null, $"Could not find method `{fieldName}` on object `{type}`");
40+
41+
return fi;
42+
}
43+
44+
/// <summary>
45+
/// Sets a private field from a class
46+
/// </summary>
47+
/// <param name="fieldName">The field to change</param>
48+
/// <param name="value">The new value</param>
49+
public static void SetField(this object target, string fieldName, object value)
50+
{
51+
Assert.True(target != null, "The target could not be null");
52+
Assert.IsNotEmpty(fieldName, "The field to set could not be null");
53+
target.GetType().FindField(fieldName).SetValue(target, value);
54+
}
55+
56+
/// <summary>
57+
/// Gets the value of a private field from a class
58+
/// </summary>
59+
/// <param name="fieldName">The field to get</param>
60+
public static object GetField(this object target, string fieldName)
61+
{
62+
Assert.True(target != null, "The target could not be null");
63+
Assert.IsNotEmpty(fieldName, "The field to set could not be null");
64+
return target.GetType().FindField(fieldName).GetValue(target);
65+
}
66+
67+
/// <summary>
68+
/// Gets all the fields from a class
69+
/// </summary>
70+
public static IEnumerable<FieldInfo> GetFields(this object target)
71+
{
72+
Assert.True(target != null, "The target could not be null");
73+
74+
return target.GetType()
75+
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
76+
.OrderBy(t => t.MetadataToken);
77+
}
78+
}
79+
}

com.unity.render-pipelines.core/Tests/Editor/ReflectionUtils.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

com.unity.render-pipelines.core/Tests/Editor/Volumes.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)