• 2018年全军院校招生计划下达:计划招收学员3.05万名 2019-06-15
  • 晋城市举办干部素质提升工程第十八期专题讲座 2019-06-15
  • 抖音广告出现对英烈邱少云不敬内容 今日头条致歉 2019-06-13
  • 超半数巴西民众对世界杯不感兴趣--旅游频道 2019-06-12
  • 外交部举行中外媒体吹风会:王毅介绍上合组织青岛峰会情况 2019-06-12
  • 2018网络中国节·端午 2019-06-04
  • 韩媒:韩美商定暂停原定8月“乙支自由卫士”联演 2019-06-03
  • 重庆市公安局交通管理局互联网交通安全服务管理平台 2019-06-03
  • 俄侦察船穿越英吉利海峡 英国急派军舰战机监视 2019-05-28
  • 网购陷阱多 女子花3000元买5套化妆品只有2套是真的 2019-05-28
  • 环保约谈濂溪区主要负责同志 谢一平要求立行立改真抓真改 2019-05-25
  • 官宣!广东签约北京3冠功勋 大莫助拳阿联未来可期 2019-05-25
  • 党建第一责任与发展第一要务相融合br全面提升机关党建工作水平 2019-05-22
  • 卡纳瓦罗:对比赛结果不满意 晋级机会各占一半 2019-05-22
  • 天津宣讲十九大:津沽大地舞春风,小康路上添豪情 2019-05-21
  • 南粤36选7最新开奖号码: 志远 【UGUI】UGUI的Drag拖拽与游戏物体的Drop进行交互

    42
    回复
    4315
    查看
    打印 上一主题 下一主题
    [ 复制链接 ]
    排名
    9398
    昨日变化

    福建36选7和值走势图 www.00-na.com 12

    主题

    209

    帖子

    991

    积分

    Rank: 9Rank: 9Rank: 9

    UID
    21402
    好友
    13
    蛮牛币
    24
    威望
    0
    注册时间
    2014-4-14
    在线时间
    489 小时
    最后登录
    2019-6-27

    认证开发者

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

    您需要 登录 才可以下载或查看,没有帐号?注册帐号

    x
    本帖最后由 zhiyuan 于 2019-3-1 11:58 编辑

    #0x001  需求
    Unity事件系统EventSystems在对于UGUI之间的OnDrag和OnDrop完全没问题,但是对于UGUI和游戏物体的交互就会出现一些情况,我们要实现一个让UGUI和游戏物体之间的OnDrag和OnDrop。
    当然你非要用自己的射线进行检测,我也不说什么,但是为了高效的进行开发,做一些疯狂的事情是有必要的!

    #0x002 分析
    引入一个国外路人的提问以及热心道友的回答
    [how do you use IDropHandler.OnDrop with 3D objects?]
    https://forum.unity.com/threads/eventsystem-how-do-you-use-idrophandler-ondrop-with-3d-objects.317683/

    经过测试发现确实是UGUI的射线遮挡(Raycast Target)选项影响了我们的3D射线输入组件(PhysicsRaycaster)的正常运行,用道友的方法确实是可以实现效果,但是并不稳定也不够高效和严谨,更不用说代码复用了,对此我提出一个好想法!
    再次引入momo大神的文章
    [研究院之将UI的点击事件渗透下去]  //www.xuanyusong.com/archives/4241
    那么我们就让UGUI的OnDrop事件渗透到3D物体上去吧=-=

    #####补充
    通过momo大神的文章得知EventSystem.current.RaycastAll(, );可以得到所有射线检测的物体
    其实我们是间接利用了系统EventSystem的射线。

    通过反编译得知函数RaycastAll对返回值 List 做了排序(sort)操作 因此我们不需要进行前后排序。
    #0x003 实现步骤
    #####1. 编写BaseDrag抽象基类
    [C#] 纯文本查看 复制代码
    using UnityEngine;
    using UnityEngine.EventSystems;
    using System.Collections.Generic;
    public abstract class BaseDrag :MonoBehaviour, IDragHandler,IEndDragHandler,IBeginDragHandler
    {
        public bool dropAll = false;
        /// <summary>
        /// 拖拽开始
        /// </summary>
        /// <param name="eventData"></param>
        public abstract void OnBeginDrag(PointerEventData eventData);
        /// <summary>
        /// 拖拽中
        /// </summary>
        /// <param name="eventData"></param>
        public abstract void OnDrag(PointerEventData eventData);
        /// <summary>
        /// 拖拽结束
        /// </summary>
        /// <param name="eventData"></param>
        public virtual void OnEndDrag(PointerEventData eventData)
        {
            if (dropAll)
                PassEvent(eventData, ExecuteEvents.dropHandler);
        }
        //把事件透下去
        public void PassEvent<T>(PointerEventData data, ExecuteEvents.EventFunction<T> function)
            where T : IEventSystemHandler
        {
            List<RaycastResult> results = new List<RaycastResult>();
            
            EventSystem.current.RaycastAll(data, results);
            ///用真正的当前拖拽的物体做判断
            GameObject current = data.pointerDrag; 
            for (int i = 0; i < results.Count; i++)
            {
                if (current != results[i].gameObject)[/i]
    [i]            {[/i]
    [i]                ///如果是3D物体的射线那么就直接赋值到原数据,传递到下一个组件。[/i]
    [i]                ///这里是为了用户能拿到当前射线打到3D物体的世界坐标。[/i]
    [i]                ///方便用户自己处理 不需要再次发射射线。[/i]
    [i]                data.pointerPressRaycast = results;[/i]
    [i]                ExecuteEvents.Execute(results.gameObject, data, function);[/i]
    [i]            }[/i]
    [i]        }[/i]
    [i]    }[/i]
    [i]}

    此类规定了拖拽类的基本事件,以及实现了事件的渗透,和控制开关dropAll 并且继承MonoBehaviour
    #####2. 编写UIDrag用户实际实现类这里为了方便,直接找一个网上已经实现的UI拖拽类进行重构
    [UGUI拖拽类](https://www.cnblogs.com/mrmocha/p/8040649.html)
    重构后代码
    [C#] 纯文本查看 复制代码
    using UnityEngine;
    using UnityEngine.EventSystems;
    
    public class UIDrag : BaseDrag
    {
        [Header("是否精准拖拽")]
        public bool m_isPrecision = true;
    
        //存储图片中心点与鼠标点击点的偏移量
        private Vector3 m_offset;
    
        //存储当前拖拽图片的RectTransform组件
        private RectTransform m_rt;
        void Start()
        {
            //初始化
            m_rt = gameObject.GetComponent<RectTransform>();
        }
    
        //开始拖拽触发
        public override void OnBeginDrag(PointerEventData eventData)
        {
            //如果精确拖拽则进行计算偏移量操作
            if (m_isPrecision)
            {
                // 存储点击时的鼠标坐标
                Vector3 tWorldPos;
                //UI屏幕坐标转换为世界坐标
                RectTransformUtility.ScreenPointToWorldPointInRectangle(m_rt, eventData.position, eventData.pressEventCamera, out tWorldPos);
                //计算偏移量   
                m_offset = transform.position - tWorldPos;
            }
            //否则,默认偏移量为0
            else
            {
                m_offset = Vector3.zero;
            }
    
            SetDraggedPosition(eventData);
        }
    
        //拖拽过程中触发
        public override void OnDrag(PointerEventData eventData)
        {
            SetDraggedPosition(eventData);
        }
    
        //结束拖拽触发
        public override void OnEndDrag(PointerEventData eventData)
        {
            SetDraggedPosition(eventData);
            base.OnEndDrag(eventData);
        }
    
        /// <summary>
        /// 设置图片位置方法
        /// </summary>
        /// <param name="eventData"></param>
        private void SetDraggedPosition(PointerEventData eventData)
        {
            //存储当前鼠标所在位置
            Vector3 globalMousePos;
            //UI屏幕坐标转换为世界坐标
            if (RectTransformUtility.ScreenPointToWorldPointInRectangle(m_rt, eventData.position, eventData.pressEventCamera, out globalMousePos))
            {
                //设置位置及偏移量
                m_rt.position = globalMousePos + m_offset;
            }
        }
    }


    继承对象改为BaseDrag,并把原本的OnBeginDrag、OnDrag、OnEndDrag 方法前加上override (重写)
    注意OnEndDrag方法最后加上base.OnEndDrag(eventData);调回父类实现穿透。
    创建一个Button挂载UIDrag ,并点上DropAll。


    创建一个测试接收脚本DropTest挂载到一个Cube上
    [C#] 纯文本查看 复制代码
    public class DropTest : EventTrigger
    {
        public override void OnDrop(PointerEventData eventData)
        {
            Debug.Log("我收到一个拖入者:"+ eventData.lastPress);
            base.OnDrop(eventData);
        }
    }






    ####补充:别忘了给摄像机挂载PhysicsRaycaster组件哦?。。。?!
    #0x004 实现效果






    参与人数 3鲜花 +13 收起 理由
    RyeCat + 3 很给力!
    smz2287711279 + 5 很给力!
    1320494699 + 5 赞一个!

    查看全部评分总评分 : 鲜花 +13

    本帖被以下淘专辑推荐:

    2初来乍到
    117/150
    排名
    16218
    昨日变化

    0

    主题

    26

    帖子

    117

    积分

    Rank: 2Rank: 2

    UID
    207231
    好友
    1
    蛮牛币
    7490
    威望
    0
    注册时间
    2017-2-18
    在线时间
    47 小时
    最后登录
    2019-6-5
    沙发
    2019-3-1 13:39:11 只看该作者
    顶帖 占楼 抢占一楼
    5熟悉之中
    525/1000
    排名
    6775
    昨日变化

    14

    主题

    73

    帖子

    525

    积分

    Rank: 5Rank: 5

    UID
    265691
    好友
    1
    蛮牛币
    5402
    威望
    0
    注册时间
    2018-1-22
    在线时间
    242 小时
    最后登录
    2019-6-26
    板凳
    2019-3-1 13:41:38 只看该作者

    顶帖 占楼 抢占二楼
    5熟悉之中
    879/1000
    排名
    3457
    昨日变化

    1

    主题

    195

    帖子

    879

    积分

    Rank: 5Rank: 5

    UID
    238064
    好友
    5
    蛮牛币
    21008
    威望
    0
    注册时间
    2017-9-7
    在线时间
    251 小时
    最后登录
    2019-6-26
    地板
    2019-3-1 14:01:37 只看该作者
    顶顶顶
    7日久生情
    1770/5000
    排名
    2263
    昨日变化

    32

    主题

    351

    帖子

    1770

    积分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    191951
    好友
    1
    蛮牛币
    12185
    威望
    0
    注册时间
    2016-12-21
    在线时间
    765 小时
    最后登录
    2019-6-20
    5#
    2019-3-1 14:01:53 只看该作者
    牛皮啊大佬
    2初来乍到
    149/150
    排名
    12478
    昨日变化

    0

    主题

    10

    帖子

    149

    积分

    Rank: 2Rank: 2

    UID
    290252
    好友
    0
    蛮牛币
    5450
    威望
    0
    注册时间
    2018-7-18
    在线时间
    65 小时
    最后登录
    2019-6-27
    6#
    2019-3-1 14:04:39 只看该作者
    顶顶顶顶顶
    5熟悉之中
    808/1000
    排名
    3744
    昨日变化

    0

    主题

    45

    帖子

    808

    积分

    Rank: 5Rank: 5

    UID
    226917
    好友
    0
    蛮牛币
    2345
    威望
    0
    注册时间
    2017-6-15
    在线时间
    361 小时
    最后登录
    2019-6-6
    7#
    2019-3-1 14:04:53 只看该作者
    膜拜大佬
    5熟悉之中
    883/1000
    排名
    3817
    昨日变化

    0

    主题

    130

    帖子

    883

    积分

    Rank: 5Rank: 5

    UID
    246100
    好友
    0
    蛮牛币
    994
    威望
    0
    注册时间
    2017-9-26
    在线时间
    359 小时
    最后登录
    2019-5-30
    8#
    2019-3-1 14:06:16 只看该作者
    顶一下
    5熟悉之中
    803/1000
    排名
    4229
    昨日变化

    0

    主题

    52

    帖子

    803

    积分

    Rank: 5Rank: 5

    UID
    168372
    好友
    0
    蛮牛币
    9101
    威望
    0
    注册时间
    2017-1-17
    在线时间
    403 小时
    最后登录
    2019-6-10
    9#
    2019-3-1 14:11:06 只看该作者
    抱个大腿
    排名
    19337
    昨日变化

    0

    主题

    11

    帖子

    78

    积分

    Rank: 2Rank: 2

    UID
    230161
    好友
    0
    蛮牛币
    215
    威望
    0
    注册时间
    2017-7-4
    在线时间
    37 小时
    最后登录
    2019-5-24
    10#
    2019-3-1 14:11:59 只看该作者
    顶顶
    4四处流浪
    498/500
    排名
    8746
    昨日变化
    76

    0

    主题

    52

    帖子

    498

    积分

    Rank: 4

    UID
    236487
    好友
    0
    蛮牛币
    4425
    威望
    0
    注册时间
    2017-8-8
    在线时间
    310 小时
    最后登录
    2019-6-27
    11#
    2019-3-1 15:00:55 只看该作者
    3偶尔光临
    274/300
    排名
    10113
    昨日变化

    0

    主题

    79

    帖子

    274

    积分

    Rank: 3Rank: 3Rank: 3

    UID
    191422
    好友
    0
    蛮牛币
    482
    威望
    0
    注册时间
    2016-12-12
    在线时间
    87 小时
    最后登录
    2019-6-19
    12#
    2019-3-1 15:14:41 只看该作者
    大佬牛比牛比~~
    5熟悉之中
    516/1000
    排名
    6048
    昨日变化

    3

    主题

    49

    帖子

    516

    积分

    Rank: 5Rank: 5

    UID
    172616
    好友
    0
    蛮牛币
    3101
    威望
    0
    注册时间
    2016-9-28
    在线时间
    236 小时
    最后登录
    2019-6-26
    13#
    2019-3-1 18:06:18 只看该作者
    支持大佬
    7日久生情
    1535/5000
    排名
    3443
    昨日变化

    0

    主题

    895

    帖子

    1535

    积分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    210390
    好友
    0
    蛮牛币
    1835
    威望
    0
    注册时间
    2017-3-7
    在线时间
    206 小时
    最后登录
    2019-5-23
    14#
    2019-3-2 09:23:44 只看该作者
    6蛮牛粉丝
    1050/1500
    排名
    5543
    昨日变化

    0

    主题

    657

    帖子

    1050

    积分

    Rank: 6Rank: 6Rank: 6

    UID
    300432
    好友
    1
    蛮牛币
    1450
    威望
    0
    注册时间
    2018-10-18
    在线时间
    133 小时
    最后登录
    2019-3-27
    15#
    2019-3-2 09:25:59 只看该作者
    资源很棒!感谢楼主
    您需要登录后才可以回帖 登录 | 注册帐号

    本版积分规则

  • 2018年全军院校招生计划下达:计划招收学员3.05万名 2019-06-15
  • 晋城市举办干部素质提升工程第十八期专题讲座 2019-06-15
  • 抖音广告出现对英烈邱少云不敬内容 今日头条致歉 2019-06-13
  • 超半数巴西民众对世界杯不感兴趣--旅游频道 2019-06-12
  • 外交部举行中外媒体吹风会:王毅介绍上合组织青岛峰会情况 2019-06-12
  • 2018网络中国节·端午 2019-06-04
  • 韩媒:韩美商定暂停原定8月“乙支自由卫士”联演 2019-06-03
  • 重庆市公安局交通管理局互联网交通安全服务管理平台 2019-06-03
  • 俄侦察船穿越英吉利海峡 英国急派军舰战机监视 2019-05-28
  • 网购陷阱多 女子花3000元买5套化妆品只有2套是真的 2019-05-28
  • 环保约谈濂溪区主要负责同志 谢一平要求立行立改真抓真改 2019-05-25
  • 官宣!广东签约北京3冠功勋 大莫助拳阿联未来可期 2019-05-25
  • 党建第一责任与发展第一要务相融合br全面提升机关党建工作水平 2019-05-22
  • 卡纳瓦罗:对比赛结果不满意 晋级机会各占一半 2019-05-22
  • 天津宣讲十九大:津沽大地舞春风,小康路上添豪情 2019-05-21
  • 福彩七乐彩开奖号查询 我以前看的上海快三 本站新疆喜乐彩 河南快赢481开奖信息 028公式规律一码中特 福建体彩22选5走势图表 友博真人龙虎斗 中国体彩网官方首页江苏 福建十一选五预测软件 捕鱼达人开发 浙江20选5开奖结果查询今天 腾讯分分彩计划精准版 6场半全场14087预测 四肖中特中后付款 今天山西快乐十分开奖