【Unity】用鼠标滚轮控制UGUI中的Scroll View

这个需求是玩家测试出来的。本来默认按下左键就可以滑动Scroll View,但是好几个玩家一上来就用鼠标滚轮,然后只见那个Scroll View就巨缓慢地移动,令人窒息(其实从这里可以看出,这个组件本身是支持鼠标滚轮事件的,只是速度有些慢)。

因此增加需求:不影响默认左键控制的情况下,使得鼠标滚轮也可以控制Scroll View的滑动。

解决方案:

1.直接在面板上改动Scroll Rect组件的 Scroll Sensitivity属性,增大,目测设置为50比较合适。

Unity官方文档:

Scroll Sensitivity The sensitivity to scroll wheel and track pad scroll events.
事实证明,以后遇到问题一定要首先认认真真读文档。

2.原本没有发现这个属性(坑爹啊),以为要扩展功能。于是手动重写了Scroll Rect的滚动事件才发现,有一个参数已经在面板中暴露出来了。下面是过程:(如果大家还有别的需求,比如兼容鼠标右键、中键等可以参考)

查看Unity UGUI中ScrollRect的源代码,准备对ScrollRect组件进行扩展:

https://bitbucket.org/Unity-Technologies/ui/src/a3f89d5f7d145e4b6fa11cf9f2de768fea2c500f/UnityEngine.UI/UI/Core/ScrollRect.cs?at=2017.3&fileviewer=file-view-default

首先发现在拖动事件这里是这样写的:

 public virtual void OnBeginDrag(PointerEventData eventData)
        {
            if (eventData.button != PointerEventData.InputButton.Left)
                return;//看这里,不是左键就返回了。

            if (!IsActive())
                return;

            UpdateBounds();

            m_PointerStartLocalCursor = Vector2.zero;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(viewRect, eventData.position, eventData.pressEventCamera, out m_PointerStartLocalCursor);
            m_ContentStartPosition = m_Content.anchoredPosition;
            m_Dragging = true;
        }

如果这个拖动事件的按钮想要兼容其他按钮,可以这样写:

using UnityEngine.UI;
using UnityEngine.EventSystems;
 
 public class MiddleScrollRect : ScrollRect
 {
     public override void OnBeginDrag(PointerEventData eventData)
     {
         if (eventData.button == PointerEventData.InputButton.Left||eventData.button == PointerEventData.InputButton.Right)
         {//兼容鼠标左键和右键
             eventData.button = PointerEventData.InputButton.Left;
             base.OnBeginDrag(eventData);
         } 
     }
 //下面两个方法也要进行类似的改写,先兼容其他按键,再调用父类的对应方法
     public override void OnEndDrag(PointerEventData eventData) {}
 
     public override void OnDrag(PointerEventData eventData) {}

我的目标是重写滑动事件的接口,加快滑动的速度。新建一个脚本,继承自ScrollRect,添加如下函数:

 public override void OnScroll(PointerEventData data)
    {
        if (!IsActive())
            return;

        UpdateBounds();

        Vector2 delta = data.scrollDelta;
        // Down is positive for scroll events, while in UI system up is positive.
        delta.y *= -35;//增加这个绝对值或者在面板上增大ScrollSensitivity
        if (vertical && !horizontal)
        {
            if (Mathf.Abs(delta.x) > Mathf.Abs(delta.y))
                delta.y = delta.x;
            delta.x = 0;
        }
        if (horizontal && !vertical)
        {
            if (Mathf.Abs(delta.y) > Mathf.Abs(delta.x))
                delta.x = delta.y;
            delta.y = 0;
        }

        Vector2 position = content.anchoredPosition;
        position += delta * scrollSensitivity;//注意:这里父类中调用的是一个private属性,子类只能访问public属性
        //同时删除了对于Clamped/Elastic拖动方式的判断,因为这里的代码也有一定保护级别,不过暂时已经满足我的需求了
        SetContentAnchoredPosition(position);
        UpdateBounds();
    }
}

3.对ScrollRect进行扩展后,用我的脚本替代原来的Scroll组件就可以了。



猜你喜欢

转载自blog.csdn.net/qq_36622009/article/details/80626127
今日推荐