Files
test/Assets/EditorAttributes/Editor/Scripts/Drawers/NumericalAttributeDrawers/ClampDrawer.cs
T

170 lines
6.7 KiB
C#

using UnityEngine;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace EditorAttributes.Editor
{
[CustomPropertyDrawer(typeof(ClampAttribute))]
public class ClampDrawer : PropertyDrawerBase
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var clampAttribute = attribute as ClampAttribute;
var minMaxX = (clampAttribute.MinValueX, clampAttribute.MaxValueX);
var minMaxY = (clampAttribute.MinValueY, clampAttribute.MaxValueY);
var minMaxZ = (clampAttribute.MinValueZ, clampAttribute.MaxValueZ);
var minMaxW = (clampAttribute.MinValueW, clampAttribute.MaxValueW);
var root = new VisualElement();
var propertyField = CreatePropertyField(property);
var helpBox = new HelpBox("", HelpBoxMessageType.Warning);
root.RegisterCallback<SerializedPropertyChangeEvent>((e) =>
{
switch (property.propertyType)
{
case SerializedPropertyType.Integer:
switch (property.numericType)
{
default:
case SerializedPropertyNumericType.Int32:
property.intValue = (int)Mathf.Clamp(property.intValue, minMaxX.MinValueX, minMaxX.MaxValueX);
propertyField.Q<IntegerField>().SetValueWithoutNotify(property.intValue);
break;
case SerializedPropertyNumericType.UInt32:
property.uintValue = (uint)Mathf.Clamp(property.uintValue, minMaxX.MinValueX, minMaxX.MaxValueX);
propertyField.Q<UnsignedIntegerField>().SetValueWithoutNotify(property.uintValue);
break;
case SerializedPropertyNumericType.Int64:
property.longValue = (long)Mathf.Clamp(property.longValue, minMaxX.MinValueX, minMaxX.MaxValueX);
propertyField.Q<LongField>().SetValueWithoutNotify(property.longValue);
break;
case SerializedPropertyNumericType.UInt64:
property.ulongValue = (ulong)Mathf.Clamp(property.ulongValue, minMaxX.MinValueX, minMaxX.MaxValueX);
propertyField.Q<UnsignedLongField>().SetValueWithoutNotify(property.ulongValue);
break;
}
break;
case SerializedPropertyType.Float:
switch (property.numericType)
{
case SerializedPropertyNumericType.Float:
property.floatValue = Mathf.Clamp(property.floatValue, minMaxX.MinValueX, minMaxX.MaxValueX);
propertyField.Q<FloatField>().SetValueWithoutNotify(property.floatValue);
break;
case SerializedPropertyNumericType.Double:
property.doubleValue = Mathf.Clamp((float)property.doubleValue, minMaxX.MinValueX, minMaxX.MaxValueX);
propertyField.Q<DoubleField>().SetValueWithoutNotify(property.doubleValue);
break;
}
break;
case SerializedPropertyType.Vector2:
property.vector2Value = ClampVector(minMaxX, minMaxY, minMaxZ, minMaxW, property.vector2Value);
propertyField.Q<Vector2Field>().SetValueWithoutNotify(property.vector2Value);
break;
case SerializedPropertyType.Vector2Int:
property.vector2IntValue = VectorUtils.Vector3IntToVector2Int(ClampIntVector(minMaxX, minMaxY, minMaxZ, minMaxW, new(property.vector2IntValue.x, property.vector2IntValue.y)));
propertyField.Q<Vector2IntField>().SetValueWithoutNotify(property.vector2IntValue);
break;
case SerializedPropertyType.Vector3:
property.vector3Value = ClampVector(minMaxX, minMaxY, minMaxZ, minMaxW, property.vector3Value);
propertyField.Q<Vector3Field>().SetValueWithoutNotify(property.vector3Value);
break;
case SerializedPropertyType.Vector3Int:
property.vector3IntValue = ClampIntVector(minMaxX, minMaxY, minMaxZ, minMaxW, property.vector3IntValue);
propertyField.Q<Vector3IntField>().SetValueWithoutNotify(property.vector3IntValue);
break;
case SerializedPropertyType.Rect:
property.rectValue = ClampRect(minMaxX, minMaxY, minMaxZ, minMaxW, property.rectValue);
propertyField.Q<RectField>().SetValueWithoutNotify(property.rectValue);
break;
case SerializedPropertyType.RectInt:
property.rectIntValue = ClampIntRect(minMaxX, minMaxY, minMaxZ, minMaxW, property.rectIntValue);
propertyField.Q<RectIntField>().SetValueWithoutNotify(property.rectIntValue);
break;
case SerializedPropertyType.Vector4:
helpBox.text = "Vector4's are not supported";
root.Add(helpBox);
return;
case SerializedPropertyType.Quaternion:
helpBox.text = "Quaternions are not supported because they are weird";
root.Add(helpBox);
return;
default:
helpBox.text = "The attached field must be numerical";
root.Add(helpBox);
return;
}
property.serializedObject.ApplyModifiedProperties();
});
root.Add(propertyField);
return root;
}
private Vector4 ClampVector((float, float) minMaxX, (float, float) minMaxY, (float, float) minMaxZ, (float, float) minMaxW, Vector4 vectorValue)
{
ClampAxis(minMaxX, minMaxY, minMaxZ, minMaxW, ref vectorValue);
return vectorValue;
}
private Rect ClampRect((float, float) minMaxX, (float, float) minMaxY, (float, float) minMaxZ, (float, float) minMaxW, Rect rectValue)
{
var vector4 = new Vector4(rectValue.x, rectValue.y, rectValue.width, rectValue.height);
ClampAxis(minMaxX, minMaxY, minMaxZ, minMaxW, ref vector4);
return new Rect(vector4.x, vector4.y, vector4.z, vector4.w);
}
private Vector3Int ClampIntVector((float, float) minMaxX, (float, float) minMaxY, (float, float) minMaxZ, (float, float) minMaxW, Vector3Int vectorValue)
{
var vector4 = new Vector4(vectorValue.x, vectorValue.y, vectorValue.z);
ClampAxis(minMaxX, minMaxY, minMaxZ, minMaxW, ref vector4);
return new Vector3Int((int)vector4.x, (int)vector4.y, (int)vector4.z);
}
private RectInt ClampIntRect((float, float) minMaxX, (float, float) minMaxY, (float, float) minMaxZ, (float, float) minMaxW, RectInt rectValue)
{
var vector4 = new Vector4(rectValue.x, rectValue.y, rectValue.width, rectValue.height);
ClampAxis(minMaxX, minMaxY, minMaxZ, minMaxW, ref vector4);
return new RectInt((int)vector4.x, (int)vector4.y, (int)vector4.z, (int)vector4.w);
}
private void ClampAxis((float, float) minMaxX, (float, float) minMaxY, (float, float) minMaxZ, (float, float) minMaxW, ref Vector4 vector)
{
var x = Mathf.Clamp(vector.x, minMaxX.Item1, minMaxX.Item2);
var y = Mathf.Clamp(vector.y, minMaxY.Item1, minMaxY.Item2);
var z = Mathf.Clamp(vector.z, minMaxZ.Item1, minMaxZ.Item2);
var w = Mathf.Clamp(vector.w, minMaxW.Item1, minMaxW.Item2);
vector = new Vector4(x, y, z, w);
}
}
}