新宝娱乐城百家乐: 志远 【UGUI】UGUI的Drag拖拽与游戏物体的Drop进行交互

39
回复
3851
查看
打印 上一主题 下一主题
[ 复制链接 ]
排名
9396
昨日变化

新宝娱乐城博彩打不开 www.sl6cl.com.cn 12

主题

207

帖子

961

积分

Rank: 9Rank: 9Rank: 9

UID
21402
好友
12
蛮牛币
89
威望
0
注册时间
2014-4-14
在线时间
461 小时
最后登录
2019-5-22

认证开发者

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

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

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初来乍到
116/150
排名
16217
昨日变化

0

主题

26

帖子

116

积分

Rank: 2Rank: 2

UID
207231
好友
1
蛮牛币
7488
威望
0
注册时间
2017-2-18
在线时间
46 小时
最后登录
2019-4-25
沙发
2019-3-1 13:39:11 只看该作者
顶帖 占楼 抢占一楼
4四处流浪
496/500
排名
6774
昨日变化

13

主题

68

帖子

496

积分

Rank: 4

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

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

1

主题

177

帖子

842

积分

Rank: 5Rank: 5

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

32

主题

351

帖子

1767

积分

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

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

0

主题

9

帖子

133

积分

Rank: 2Rank: 2

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

0

主题

45

帖子

805

积分

Rank: 5Rank: 5

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

0

主题

130

帖子

880

积分

Rank: 5Rank: 5

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

0

主题

52

帖子

798

积分

Rank: 5Rank: 5

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

0

主题

11

帖子

77

积分

Rank: 2Rank: 2

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

0

主题

37

帖子

411

积分

Rank: 4

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

0

主题

73

帖子

262

积分

Rank: 3Rank: 3Rank: 3

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

3

主题

49

帖子

512

积分

Rank: 5Rank: 5

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

0

主题

893

帖子

1532

积分

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

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

0

主题

658

帖子

1051

积分

Rank: 6Rank: 6Rank: 6

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

本版积分规则

  • 中国智能手机在东南亚受追捧 2019-05-22
  • 一语惊坛(5月10日):半岛和平,是中朝两国的共同愿望。 2019-05-22
  • 董卿白岩松朱广权 看看央视主持人大学就读啥院系 2019-05-21
  • 邓超陈冠希焦恩俊,刷新娱乐圈女儿奴新高度 2019-05-21
  • 紫光阁中共中央国家机关工作委员会 2019-05-20
  • 四个跌停后 金洲慈航不惜食言也要选择如此停牌自救 2019-05-19
  • 无论是否想怀孕 这串数字女性要知道 2019-05-18
  • 机遇与挑战并存 中国企业“走出去”行稳致远 2019-05-17
  • 中国算是世界杯中最能长期保持着稳定成绩的一个了。 2019-05-17
  • 回复@笑傲江湖V:中国人啥不炒?君子兰、普洱茶、大蒜……凡事保存周期比较长的都有人炒,跟市场经济充不充分有啥关系? 2019-05-16
  • 特朗普威胁中国,如果中国报复性征收美国高关税,美国将征收中国额外关税,特朗普真流氓。难道中国是吓大的? 2019-05-15
  • 那请你具体的指出,中国现在哪一个人不是中国人? 2019-05-15
  • 劳动不是人的本质,对劳动成果即社会财富的占有才是人的本质。在私有制阶级社会中,劳动成果即社会财富被剥削阶级无偿占有,所以人的本质便表现为阶级本质,“每... 2019-05-14
  • 丰富产品序列 曝力帆轩朗纯电动申报图 2019-05-14
  • 把党的领导贯穿军事科研工作各方面和全过程 2019-05-13
  • 979| 157| 73| 951| 907| 403| 179| 291| 147| 403|