如何设置带最小最大值约束的双值滑块Inspector属性?
Unity实现双值范围滑块(类似Spot Light 2D的Inner/Outer Angle)
要实现像Spot Light 2D组件中「Inner / Outer Spot Angle」那样的双值滑块效果,你可以通过自定义PropertyAttribute和PropertyDrawer实现,直接将Vector2(兼容类型)渲染为带输入框的双滑块,同时满足你提出的三个约束条件。
步骤1:定义自定义范围属性
创建自定义属性类,标记需要双滑块的字段并指定整体最小/最大值限制:
using UnityEngine; public class MinMaxRangeAttribute : PropertyAttribute { public readonly float minLimit; public readonly float maxLimit; public MinMaxRangeAttribute(float minLimit, float maxLimit) { this.minLimit = minLimit; this.maxLimit = maxLimit; } }
步骤2:实现自定义属性绘制器
编写PropertyDrawer处理双滑块的绘制、输入支持和值约束逻辑:
using UnityEditor; using UnityEngine; [CustomPropertyDrawer(typeof(MinMaxRangeAttribute))] public class MinMaxRangeDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { var rangeAttribute = attribute as MinMaxRangeAttribute; // 仅支持Vector2类型(元组在Unity序列化中支持有限,推荐用Vector2) if (property.propertyType != SerializedPropertyType.Vector2) { EditorGUI.LabelField(position, label.text, "仅支持Vector2类型"); return; } // 拆分绘制区域:标签、滑块、输入框 var labelRect = new Rect(position.x, position.y, EditorGUIUtility.labelWidth, position.height); var sliderRect = new Rect(position.x + EditorGUIUtility.labelWidth, position.y, position.width - EditorGUIUtility.labelWidth - 100, position.height); var minInputRect = new Rect(position.x + position.width - 95, position.y, 45, position.height); var maxInputRect = new Rect(position.x + position.width - 45, position.y, 45, position.height); // 绘制字段标签 EditorGUI.LabelField(labelRect, label); // 获取当前值并拆分为min/max var currentValue = property.vector2Value; float min = currentValue.x; float max = currentValue.y; // 绘制双滑块 EditorGUI.MinMaxSlider(sliderRect, ref min, ref max, rangeAttribute.minLimit, rangeAttribute.maxLimit); // 绘制输入框并约束值:min不超过max,且整体在设定范围内 min = EditorGUI.FloatField(minInputRect, Mathf.Clamp(min, rangeAttribute.minLimit, max)); max = EditorGUI.FloatField(maxInputRect, Mathf.Clamp(max, min, rangeAttribute.maxLimit)); // 更新属性值 property.vector2Value = new Vector2(min, max); } }
步骤3:在代码中使用
在MonoBehaviour脚本中,用[MinMaxRange]标记Vector2字段即可:
using UnityEngine; public class LightSettings : MonoBehaviour { // 模拟Spot Light 2D的Inner/Outer角度范围 [MinMaxRange(0f, 180f)] public Vector2 spotAngles; // 其他双范围需求示例 [MinMaxRange(0f, 1f)] public Vector2 intensityRange; }
效果说明
- 整体范围约束:通过
[MinMaxRange(min, max)]指定的范围,会限制滑块和输入框的可调节边界。 - 手动输入支持:滑块右侧的两个输入框可直接输入min和max数值。
- 自动约束min<=max:拖动滑块或输入数值时,会自动确保min值不大于max值,避免无效数据。
内容的提问来源于stack exchange,提问作者danikaze
相关产品推荐
相关产品推荐

