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

如何将EditorGUILayout.FloatField的标签后置并替换为纹理?

当然可以不用折腾一堆辅助类!咱们直接靠Unity编辑器自带的布局工具和事件系统就能搞定,思路其实很直白:

实现步骤

1. 手动拆分布局:输入框在前,纹理标签在后

原生的EditorGUILayout.FloatField会把标签硬怼在前面,咱们直接拆成两部分渲染就行——用HorizontalScope把输入框和纹理放在同一行,先渲染不带标签的输入框,再渲染你的纹理。

代码示例:

// 在编辑器窗口的OnGUI方法内
private Texture2D _dragIcon; // 提前赋值你的纹理,比如从Resources加载或者直接拖入
private float _targetValue = 0f;

void OnGUI()
{
    // 开启水平布局,让输入框和纹理在同一行
    using (new EditorGUILayout.HorizontalScope())
    {
        // 渲染不带标签的FloatField,用GUIContent.none隐藏默认标签
        _targetValue = EditorGUILayout.FloatField(GUIContent.none, _targetValue);

        if (_dragIcon != null)
        {
            // 先获取纹理要占据的矩形区域,再绘制纹理
            Rect iconRect = GUILayoutUtility.GetRect(_dragIcon, GUIStyle.none, 
                GUILayout.Width(22), GUILayout.Height(22)); // 大小可以按需调整
            GUI.DrawTexture(iconRect, _dragIcon, ScaleMode.ScaleToFit);
        }
    }
}

2. 监听鼠标事件,复刻原生拖拽修改逻辑

接下来要让点击纹理拖拽时能改数值,这部分直接用Unity的Event系统捕获鼠标的按下、拖拽、抬起事件就行,完全不用自定义控件:

把上面的代码扩展一下,加入事件监听:

private bool _isDragging = false;
private float _lastMouseY;

void OnGUI()
{
    using (new EditorGUILayout.HorizontalScope())
    {
        _targetValue = EditorGUILayout.FloatField(GUIContent.none, _targetValue);

        if (_dragIcon != null)
        {
            Rect iconRect = GUILayoutUtility.GetRect(_dragIcon, GUIStyle.none, 
                GUILayout.Width(22), GUILayout.Height(22));
            GUI.DrawTexture(iconRect, _dragIcon, ScaleMode.ScaleToFit);

            // 获取当前事件
            Event currentEvent = Event.current;
            switch (currentEvent.type)
            {
                // 鼠标按下时,判断是否点击在纹理区域内
                case EventType.MouseDown:
                    if (iconRect.Contains(currentEvent.mousePosition))
                    {
                        _isDragging = true;
                        _lastMouseY = currentEvent.mousePosition.y;
                        currentEvent.Use(); // 标记事件已处理,避免干扰其他控件
                    }
                    break;

                // 拖拽时计算鼠标偏移,修改数值
                case EventType.MouseDrag:
                    if (_isDragging)
                    {
                        // 计算鼠标上下移动的差值,向上拖数值增加,向下减少
                        float delta = _lastMouseY - currentEvent.mousePosition.y;
                        // 这里的0.1是灵敏度,可按需调整,按住Shift/Alt还能加减速
                        float sensitivity = 0.1f;
                        if (currentEvent.shift) sensitivity *= 2f;
                        if (currentEvent.alt) sensitivity *= 0.2f;
                        
                        _targetValue += delta * sensitivity;
                        // 可选:限制数值范围
                        _targetValue = Mathf.Clamp(_targetValue, 0f, 100f);
                        
                        _lastMouseY = currentEvent.mousePosition.y;
                        currentEvent.Use();
                        Repaint(); // 强制刷新窗口,实时显示数值变化
                    }
                    break;

                // 鼠标抬起时结束拖拽状态
                case EventType.MouseUp:
                    _isDragging = false;
                    break;
            }
        }
    }
}

3. 细节优化(可选)

  • 纹理样式适配:如果想让纹理看起来更像原生标签,可以用GUI.skin.label的样式来绘制,去掉不必要的边框:
    GUIStyle iconStyle = new GUIStyle(GUI.skin.label);
    iconStyle.border = new RectOffset(0, 0, 0, 0);
    Rect iconRect = GUILayoutUtility.GetRect(_dragIcon, iconStyle, ...);
    
  • 数值格式化:如果需要显示固定小数位数,可以用EditorGUILayout.FloatField的重载版本,指定小数位数:
    _targetValue = EditorGUILayout.FloatField(GUIContent.none, _targetValue, 2);
    

这样就完全不需要额外的辅助类,所有逻辑都在编辑器窗口的OnGUI方法里完成,效果和原生FloatField的拖拽修改完全一致,还满足了标签后置、替换成纹理的需求。

内容的提问来源于stack exchange,提问作者Alexey Shimansky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:15:52