You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设置带最小最大值约束的双值滑块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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 22:49:57