Skip to content

Commit 61ac7a4

Browse files
🔀 Merge develop into main
2 parents f61f693 + ef9e942 commit 61ac7a4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+3420
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,6 @@ fabric.properties
101101

102102
## Unity editor user settings
103103
UserSettings/*
104+
105+
# Obsidian
106+
.obsidian/

Assets/Libraries.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.

Assets/Libraries/MinMaxRangeAttribute.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.

Assets/Libraries/MinMaxRangeAttribute/Editor.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.
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
using System;
2+
using UnityEditor;
3+
using UnityEngine;
4+
5+
namespace SneakySquirrelLabs.MinMaxRangeAttribute.Editor
6+
{
7+
[CustomPropertyDrawer(typeof(MinMaxRangeAttribute))]
8+
internal class MinMaxRangeDrawer : PropertyDrawer
9+
{
10+
#region Fields
11+
12+
private const float HorizontalSpacing = 5f;
13+
private const float SliderHandlerWidth = 12f;
14+
15+
private static readonly float VerticalSpacing = EditorGUIUtility.standardVerticalSpacing;
16+
private static GUIStyle LabelStyleField;
17+
18+
private uint _decimals;
19+
20+
#endregion
21+
22+
#region Properties
23+
24+
private static GUIStyle LabelStyle => LabelStyleField ??= new GUIStyle(GUI.skin.label);
25+
26+
#endregion
27+
28+
#region Update
29+
30+
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
31+
{
32+
return base.GetPropertyHeight(property, label) * 2;
33+
}
34+
35+
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
36+
{
37+
if (attribute is not MinMaxRangeAttribute minMaxAttribute)
38+
{
39+
Debug.LogError("Min max range attribute failed to draw.");
40+
return;
41+
}
42+
43+
var minLimit = minMaxAttribute.MinLimit;
44+
var maxLimit = minMaxAttribute.MaxLimit;
45+
_decimals = minMaxAttribute.Decimals;
46+
47+
if (property.propertyType == SerializedPropertyType.Vector2Int)
48+
{
49+
var value = property.vector2IntValue;
50+
var minValue = (float)value.x;
51+
var maxValue = (float)value.y;
52+
DrawSlider(position, property, minLimit, maxLimit, ref minValue, ref maxValue, BuildIntLabel);
53+
value.x = (int)minValue;
54+
value.y = (int)maxValue;
55+
property.vector2IntValue = value;
56+
}
57+
else if (property.propertyType == SerializedPropertyType.Vector2)
58+
{
59+
var value = property.vector2Value;
60+
var minValue = value.x;
61+
var maxValue = value.y;
62+
DrawSlider(position, property, minLimit, maxLimit, ref minValue, ref maxValue, BuildFloatLabel);
63+
value.x = minValue;
64+
value.y = maxValue;
65+
property.vector2Value = value;
66+
}
67+
68+
static void DrawSlider(Rect position, SerializedProperty property, float min, float max, ref float x,
69+
ref float y, Func<float, GUIContent> buildLabel)
70+
{
71+
var consumedX = 0f;
72+
var firstLineRect = new Rect(position) { height = position.height / 2 - VerticalSpacing};
73+
74+
// Field name
75+
consumedX += DrawFieldName(firstLineRect, property);
76+
77+
// Min label
78+
var minLabel = buildLabel(min);
79+
consumedX += DrawLabel(firstLineRect, consumedX, minLabel);
80+
consumedX += HorizontalSpacing; // Add spacing between min label and slider
81+
82+
// Slider
83+
var maxLabel = buildLabel(max);
84+
var maxLabelWidth = LabelStyle.CalcSize(maxLabel).x; // We need to know the max label's size
85+
var sliderWidth = firstLineRect.width - consumedX - maxLabelWidth - HorizontalSpacing;
86+
var sliderPosition = new Rect(firstLineRect) { x = firstLineRect.x + consumedX, width = sliderWidth };
87+
EditorGUI.MinMaxSlider(sliderPosition, ref x, ref y, min, max);
88+
consumedX += sliderWidth + HorizontalSpacing;
89+
90+
// Max label
91+
DrawLabel(firstLineRect, consumedX, maxLabel);
92+
93+
// Value labels
94+
var secondLineRect = new Rect(position) { y = position.y, height = firstLineRect.height};
95+
var valuesY = secondLineRect.y + sliderPosition.height + EditorGUIUtility.standardVerticalSpacing;
96+
// X label
97+
var labelsPosition = new Rect(sliderPosition) { y = valuesY };
98+
DrawValueLabel(labelsPosition, x, min, max, true, buildLabel);
99+
// Label
100+
DrawValueLabel(labelsPosition, y, min, max, false, buildLabel);
101+
102+
static float DrawFieldName(Rect position, SerializedProperty property)
103+
{
104+
var labelPosition = new Rect(position) { width = EditorGUIUtility.labelWidth };
105+
EditorGUI.LabelField(labelPosition, property.displayName);
106+
return labelPosition.width;
107+
}
108+
109+
static float DrawLabel(Rect position, float xOffset, GUIContent label)
110+
{
111+
var size = LabelStyle.CalcSize(label);
112+
var minLabelPosition = new Rect(position) { x = position.x + xOffset, width = size.x};
113+
EditorGUI.LabelField(minLabelPosition, label, LabelStyle);
114+
return size.x;
115+
}
116+
117+
static void DrawValueLabel(Rect position, float value, float minLimit, float maxLimit,
118+
bool applyExtraOffset, Func<float, GUIContent> buildLabel)
119+
{
120+
var label = buildLabel(value);
121+
var labelSize = LabelStyle.CalcSize(label);
122+
var relativePosition = (value - minLimit) / (maxLimit - minLimit);
123+
var offset = SliderHandlerWidth / 2 + (applyExtraOffset ? -labelSize.x : 0);
124+
var totalWidth = position.width - SliderHandlerWidth;
125+
var x = position.x + relativePosition * totalWidth + offset;
126+
var labelPosition = new Rect(position) { x = x, width = labelSize.x };
127+
EditorGUI.LabelField(labelPosition, label, LabelStyle);
128+
}
129+
}
130+
131+
static GUIContent BuildIntLabel(float value) => new($"{value:F0}");
132+
133+
GUIContent BuildFloatLabel(float value)
134+
{
135+
var floatLabel = _decimals switch
136+
{
137+
0 => $"{value:F0}",
138+
1 => $"{value:F1}",
139+
2 => $"{value:F2}",
140+
3 => $"{value:F3}",
141+
_ => throw new NotSupportedException("Min max attribute supports up to 3 decimal places.")
142+
};
143+
return new GUIContent(floatLabel);
144+
}
145+
}
146+
147+
#endregion
148+
}
149+
}

Assets/Libraries/MinMaxRangeAttribute/Editor/MinMaxRangeDrawer.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "SneakySquirrelLabs.MinMaxRangeAttribute.Editor",
3+
"rootNamespace": "SneakySquirrelLabs.MinMaxRangeAttribute.Editor",
4+
"references": [
5+
"GUID:397edf9bfe7ea4399b706e9ee953b982"
6+
],
7+
"includePlatforms": [
8+
"Editor"
9+
],
10+
"excludePlatforms": [],
11+
"allowUnsafeCode": false,
12+
"overrideReferences": false,
13+
"precompiledReferences": [],
14+
"autoReferenced": true,
15+
"defineConstraints": [],
16+
"versionDefines": [],
17+
"noEngineReferences": false
18+
}

Assets/Libraries/MinMaxRangeAttribute/Editor/SneakySquirrelLabs.MinMaxRangeAttribute.Editor.asmdef.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using UnityEngine;
3+
4+
namespace SneakySquirrelLabs.MinMaxRangeAttribute
5+
{
6+
/// <summary>
7+
/// An attribute that simplifies defining bounded ranges (ranges with minimum and maximum limits) on the inspector.
8+
/// </summary>
9+
[AttributeUsage(AttributeTargets.Field)]
10+
public class MinMaxRangeAttribute : PropertyAttribute
11+
{
12+
#region Fields
13+
14+
public readonly float MinLimit;
15+
public readonly float MaxLimit;
16+
public readonly uint Decimals;
17+
18+
#endregion
19+
20+
#region Setup
21+
22+
/// <summary>
23+
/// A bounded range for integers.
24+
/// </summary>
25+
/// <param name="minLimit">The minimum acceptable value.</param>
26+
/// <param name="maxLimit">The maximum acceptable value.</param>
27+
public MinMaxRangeAttribute(int minLimit, int maxLimit)
28+
{
29+
MinLimit = minLimit;
30+
MaxLimit = maxLimit;
31+
}
32+
33+
/// <summary>
34+
/// A bounded range for floats.
35+
/// </summary>
36+
/// <param name="minLimit">The minimum acceptable value.</param>
37+
/// <param name="maxLimit">The maximum acceptable value.</param>
38+
/// <param name="decimals">How many decimals the inspector labels should display. Values must be in the [0,3]
39+
/// range. Default is 1.</param>
40+
public MinMaxRangeAttribute(float minLimit, float maxLimit, uint decimals = 1)
41+
{
42+
MinLimit = minLimit;
43+
MaxLimit = maxLimit;
44+
Decimals = decimals;
45+
}
46+
47+
#endregion
48+
}
49+
}

Assets/Libraries/MinMaxRangeAttribute/MinMaxRangeAttribute.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.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "SneakySquirrelLabs.MinMaxRangeAttribute",
3+
"rootNamespace": "SneakySquirrelLabs.MinMaxRangeAttribute",
4+
"references": [],
5+
"includePlatforms": [],
6+
"excludePlatforms": [],
7+
"allowUnsafeCode": false,
8+
"overrideReferences": false,
9+
"precompiledReferences": [],
10+
"autoReferenced": true,
11+
"defineConstraints": [],
12+
"versionDefines": [],
13+
"noEngineReferences": false
14+
}

Assets/Libraries/MinMaxRangeAttribute/SneakySquirrelLabs.MinMaxRangeAttribute.asmdef.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "com.sneakysquirrellabs.minmaxrangeattribute",
3+
"version": "1.0.0",
4+
"displayName": "Min/max range attribute",
5+
"description": "A bounded (i.e., with a minimum and maximum) range attribute for Unity's Vector2 and Vector2Int fields.",
6+
"unity": "2021.3",
7+
"documentationUrl": "https://github.com/matheusamazonas/min_max_range_attribute",
8+
"changelogUrl": "https://github.com/matheusamazonas/min_max_range_attribute/releases",
9+
"licensesUrl": "https://github.com/matheusamazonas/min_max_range_attribute/LICENSE",
10+
"keywords": [
11+
"editor",
12+
"attribute",
13+
"terrain inspector",
14+
"vector",
15+
"range"
16+
],
17+
"author": {
18+
"name": "Matheus Amazonas",
19+
"email": "matheus.amazonas@gmail.com",
20+
"url": "https://matheusamazonas.net"
21+
}
22+
}

Assets/Libraries/MinMaxRangeAttribute/package.json.meta

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

Assets/Settings.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)