UGUI拖拽与射线检测问题(背包前奏)

本文分享了使用Unity UGUI实现背包系统的经验,包括拖拽、点击效果的实现及射线检测背后的物体使其成为父物体的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



 
        最近想研究UGUI,所以只要涉及UI部分的全都想用UGUI来搞,包括之前写的回合制的一个小实例demo。但是在我研究背包所需功能的时候遇到了瓶颈,让我很是受伤。
        像是一个简单的背包,用来存储物品对象就OK了,但是那完全满足不了要求,至少像是拖拽、交换、拖入、切换栏目以及再加点炫酷特效啥的这些都要用吧!
拖拽啥的很简单,一会搞定,但是当做到射线检测的时候直接卡住了,怎么试都不没用,然后就各种查资料,找原因,包括问一些朋友。有的说能实现、有的说实现不了,但是都没有根本性解决我的问题,后来一大神朋友说,unity的UI的事件触发机制有问题,需要改一下射线触发机制,让对象主动触发事件,自己继承一下它的射线检测,如果有3D的对象,还要再自己写触发3D的,听了一下,我倒是明白了,因为我在查资料的过程中也看到这样的字眼出现,不过这要是写就不是一会的事了,我还得先研究一下这个机制,因为之前就不熟悉,要是再遇到问题,又得耗时间。
        好在,一位热心朋友的一句代码提醒了我,虽然没解决我的问题,但是却让我想到了解决的办法!下面我就把方法分享给大家:
1、拖拽以及点击效果(比较简单):
创建两个Image,命名为Item,像是背景图片啥的,你们自己放吧,创建一个脚本,随便命名,比如DragItem.cs
加上两个引用,如下:
usingUnityEngine.UI;
usingUnityEngine.EventSystems;

类继承一下IDragHandler,IPointerDownHandler,IPointerUpHandler
然后在代码里写三个方法,如下:
publicvoid OnDrag(PointerEventData eventData){
        GetComponent<RectTransform> ().pivot.Set (0, 0);
        transform.position = Input.mousePosition;
    }
 
    publicvoid OnPointerDown(PointerEventData eventData){
        transform.localScale = newVector3 (0.7f, 0.7f, 0.7f);
    }
 
    publicvoid OnPointerUp(PointerEventData eventData){
        transform.localScale = newVector3 (1f, 1f, 1f);
    }


把代码拖到两个Item上,运行程序试一下,可以看到效果
 
2、射线检测后面物体让其成为父物体
看起来简单的要命,但是却坑了我三天,射线检测机制需要自己来继承,于是我用了一个小方法,来跳过这个,等有空再用那个2D射线来搞吧
首先创建两个panel,一个命名为InitPanel,放到UI的最上面的位置,另一个就Panel不变了吧,放到最下面的位置。

在Panel上创建一个空对象取名grid,然后给其添加一个grid layout group,如下图:
 
这个组件是用来自动排序的。
代码部分,稍作修改:
//如果对象比较少可以定义一下,然后在面板中指定一下,这样节省遍历次数


[SerializeField] GameObject grid = null;
[SerializeField] GameObject initCanvas = null;


OnPointerUp 方法中加上这些:


<span style="white-space:pre">		</span>if(eventData.pointerCurrentRaycast.gameObject != null) {
                        if(eventData.pointerCurrentRaycast.gameObject.name == grid.name) {
                                transform.SetParent (grid.transform);
                        }
                }


在OnPointerDown 中加上一句:
transform.SetParent (initCanvas.transform, true);

然后在面板中指定一下,如图:
 
好了,最终效GIF动态图
 


代码改动了好多,我重新弄了个简单的贴出来给大家看看吧,加了 CanvasGroup,控制射线穿透, 还有那个PanelInit放到最下面去,还是深度和规划的问题,看起来不乱

注意一点就是如果没有CanvasGroup组件的话就添加一个

<span style="white-space:pre">	</span>publicvoid OnDrag(PointerEventData eventData){
                GetComponent<RectTransform> ().pivot.Set (0, 0);
                transform.position = Input.mousePosition;
        }
 
        publicvoid OnPointerDown(PointerEventData eventData){
                transform.localScale = newVector3 (0.7f, 0.7f, 0.7f);
                transform.SetParent (initCanvas.transform, true);
                transform.GetComponent<CanvasGroup> ().blocksRaycasts = false;
        }
 
        publicvoid OnPointerUp(PointerEventData eventData){
                transform.localScale = newVector3 (1f, 1f, 1f);
                if(eventData.pointerCurrentRaycast.gameObject != null) {
                        if(eventData.pointerCurrentRaycast.gameObject.name == grid.name) {
                                transform.SetParent (grid.transform);
                        }
                }
                transform.GetComponent<CanvasGroup> ().blocksRaycasts = true;
        }



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值