UI拖拽

作者: 迷途小路 | 来源:发表于2019-10-21 16:28 被阅读0次

    实现目标

    点住一个Image,这个Image能够跟随鼠标/触摸点的移动,松开停止移动。

    EventSystem中有这样的接口,IBeginDragHandler、IDragHandler和IEndDragHandler,在重写的方法里添加上对应的内容即可。

    public class DrogTest : MonoBehaviour, IDragHandler, IEndDragHandler, IBeginDragHandler {
    
        RectTransform rect;
        // Use this for initialization
        void Start () {
            rect = transform.GetComponent<RectTransform> ();
        }
    
        // Update is called once per frame
        void Update () {
    
        }
    
        public void OnBeginDrag (PointerEventData eventData) {
    
        }
    
        public void OnDrag (PointerEventData eventData) {
            Vector3 pos;
            RectTransformUtility.ScreenPointToWorldPointInRectangle (rect, eventData.position, eventData.enterEventCamera, out pos);
            transform.position = pos;
        }
    
        public void OnEndDrag (PointerEventData eventData) {
    
        }
    }
    

    将脚本挂载在一个GameObject上,即可看到实现了要求。

    要点

    RectTransformUtility:一个关于RectTransform的帮助类。
    ScreenPointToWorldPointInRectangle:直接翻译是“将屏幕坐标转换为矩形框里的世界坐标”。该方法的四个参数分别表示:
    1.目标Rect
    2.点击点的坐标
    3.显示这个UI的相机
    4.得到的世界坐标
    根据参数,这个方法可以理解为“触摸(从对应camera出发,是一条线)穿过目标Rect(是一个面)后相交得到的世界坐标点的坐标”,最后将得到的坐标赋予UI,即可让UI跟随鼠标。

    优化

    我们发现,每次开始拖动时,UI会位移一下,是因为代码会让UI的中心点跟随拖动点,如果拖动点一开始不在中心点,就会出现开始时的位移。那么优化的方法就是在OnPointerDown鼠标按下的方法中记录UI中心点拖动点的偏移,在给UI位置赋值时添加上这个偏移。(之所以在OnPointerDown鼠标按下的方法中添加,而不是在OnBeginDrag开始拖动这个方法中添加,是因为在判定你开始拖动的时候,鼠标已经位移了一小段距离,导致最后的跟随点与最开始按下的点有偏差。需要实现IPointerDownHandler接口)

    public void OnPointerDown (PointerEventData eventData) {
            Vector3 pos; //拖动点
            RectTransformUtility.ScreenPointToWorldPointInRectangle (rect, eventData.position, eventData.enterEventCamera, out pos);
            offset = rect.position - pos; //得到偏移值
        }
    

    全部代码如下

    using System.Collections;
    using UnityEngine;
    using UnityEngine.EventSystems;
    
    public class DrogTest : MonoBehaviour, IDragHandler, IEndDragHandler, IBeginDragHandler, IPointerDownHandler {
        RectTransform rect;
        Vector3 offset;
        // Use this for initialization
        void Start () {
            rect = transform.GetComponent<RectTransform> ();
        }
    
        // Update is called once per frame
        void Update () {
    
        }
    
        //鼠标按下时触发
        public void OnPointerDown (PointerEventData eventData) {
            Vector3 pos; //拖动点
            RectTransformUtility.ScreenPointToWorldPointInRectangle (rect, eventData.position, eventData.enterEventCamera, out pos);
            offset = rect.position - pos; //得到偏移值
        }
        
        public void OnBeginDrag (PointerEventData eventData) {
    
        }
    
        public void OnDrag (PointerEventData eventData) {
            Vector3 pos;
            RectTransformUtility.ScreenPointToWorldPointInRectangle (rect, eventData.position, eventData.enterEventCamera, out pos);
            transform.position = pos + offset;
        }
    
        public void OnEndDrag (PointerEventData eventData) {
    
        }
    }
    

    相关文章

      网友评论

          本文标题:UI拖拽

          本文链接:https://www.haomeiwen.com/subject/dkbtvctx.html