Last active
July 9, 2024 17:01
-
-
Save RiskyWilhelm/5f7a3b7c781c94657debffa712b89e36 to your computer and use it in GitHub Desktop.
Unity Vector Range/Limiter Attribute (C#>=9)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
/// <summary> Customizes the field shown in inspector and clamps the values as <see cref="RangeAttribute"/> does </summary> | |
public sealed partial class VectorRangeAttribute : PropertyAttribute | |
{ | |
public readonly (float minX, float maxX, float minY, float maxY, float minZ, float maxZ, float minW, float maxW) clamped; | |
public VectorRangeAttribute | |
( | |
float minX = float.MinValue, float maxX = float.MaxValue, | |
float minY = float.MinValue, float maxY = float.MaxValue, | |
float minZ = float.MinValue, float maxZ = float.MaxValue, | |
float minW = float.MinValue, float maxW = float.MaxValue | |
) | |
{ | |
clamped.minX = minX; | |
clamped.maxX = maxX; | |
clamped.minY = minY; | |
clamped.maxY = maxY; | |
clamped.minZ = minZ; | |
clamped.maxZ = maxZ; | |
clamped.minW = minW; | |
clamped.maxW = maxW; | |
} | |
} | |
#if UNITY_EDITOR | |
public sealed partial class VectorRangeAttribute | |
{ } | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEditor; | |
using UnityEditor.UIElements; | |
using UnityEngine; | |
using UnityEngine.UIElements; | |
[CustomPropertyDrawer(typeof(VectorRangeAttribute), true)] | |
public sealed class VectorRangeAttributeDrawer : PropertyDrawer | |
{ | |
private VectorRangeAttribute Attribute => (VectorRangeAttribute)attribute; | |
// Initialize | |
public override VisualElement CreatePropertyGUI(SerializedProperty property) | |
{ | |
// Create elements | |
var propertyElement = new PropertyField(property); | |
// Register callbacks | |
propertyElement.RegisterValueChangeCallback(OnVectorChanged); | |
return propertyElement; | |
} | |
private void OnVectorChanged(SerializedPropertyChangeEvent evt) | |
{ | |
object vectorValue = evt.changedProperty.propertyType switch | |
{ | |
SerializedPropertyType.Vector2 => (Vector2)Clamp(evt.changedProperty.vector2Value), | |
SerializedPropertyType.Vector3 => (Vector3)Clamp(evt.changedProperty.vector3Value), | |
SerializedPropertyType.Vector4 => Clamp(evt.changedProperty.vector4Value), | |
SerializedPropertyType.Vector2Int => (Vector2Int)Clamp((Vector3Int)evt.changedProperty.vector2IntValue), | |
SerializedPropertyType.Vector3Int => Clamp(evt.changedProperty.vector3IntValue), | |
_ => throw new Exception(string.Format("{0} not compitable with type {1}", nameof(VectorRangeAttribute), evt.changedProperty.propertyType)), | |
}; | |
evt.changedProperty.boxedValue = vectorValue; | |
evt.changedProperty.serializedObject.ApplyModifiedProperties(); | |
} | |
private Vector4 Clamp(Vector4 a) | |
{ | |
a.x = Math.Clamp(a.x, Attribute.clamped.minX, Attribute.clamped.maxX); | |
a.y = Math.Clamp(a.y, Attribute.clamped.minY, Attribute.clamped.maxY); | |
a.z = Math.Clamp(a.z, Attribute.clamped.minZ, Attribute.clamped.maxZ); | |
a.w = Math.Clamp(a.w, Attribute.clamped.minW, Attribute.clamped.maxW); | |
return a; | |
} | |
private Vector3Int Clamp(Vector3Int a) | |
{ | |
a.x = (int)Math.Clamp(a.x, Attribute.clamped.minX, Attribute.clamped.maxX); | |
a.y = (int)Math.Clamp(a.y, Attribute.clamped.minY, Attribute.clamped.maxY); | |
a.z = (int)Math.Clamp(a.z, Attribute.clamped.minZ, Attribute.clamped.maxZ); | |
return a; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment