一、通过添加EventTrriger组件
前提:Canvas设置
可以把EventTrriger组件看成多功能的Button组件来用
实现类似背包一样,把物品拖进槽里面
using UnityEngine;
public class Drag_3 : MonoBehaviour
{
private Vector3 startPos;
private void Start()
{
//记录UI的初始位置
startPos = transform.position;
}
public void DragMethod()
{
//UI界面,Canvas是在ScreenSpace——overlay模式下,可以直接赋值不用转换
transform.position = Input.mousePosition;
}
public void DropMethod()
{
GameObject slotlGo = GameObject.Find("Slot");
float dist = Vector3.Distance(transform.position, slotlGo.transform.position);
if (dist <= 100)
{
transform.position = slotlGo.transform.position;
}
else
{
transform.position = startPos;
}
}
}
二、通过使用接口实现UGUI的拖拽
实现类似背包一样,把物品拖进槽里面
注意:鼠标只有放在槽上方的时候松开才能判断我们拖拽这个物品是否是在槽内,只有拖拽的物品是在槽内放下的时候才有意义,即
using UnityEngine;
using UnityEngine.EventSystems;
public class Slot_4 : MonoBehaviour, IDropHandler, IDragHandler
{
//OnDrop依赖于OnDrag,先有OnDrag后OnDrop才可能被触发
public void OnDrag(PointerEventData eventData)
{
}
public void OnDrop(PointerEventData eventData)
{
Debug.LogError(2222);
if(eventData.pointerDrag != null)
{
// eventData.pointerDrag获取当前鼠标拖拽的对象
eventData.pointerDrag.GetComponent<RectTransform>().anchoredPosition
= GetComponent<RectTransform>().anchoredPosition;
}
}
}
检测拖拽事件(OnDrag)放下的操作
OnDrop依赖于OnDrag,先有OnDrag后OnDrop才可能被触发;
OnDrop事件在OnEndDrag事件(整个拖拽事件结束时调用的函数)之前执行;
拖拽放下时如果可以检测OnDrop事件的物体上方有其他物体遮挡住的当前物体,OnDrop事件也不会触发,因为屏幕射线被阻截了
解决:可以在物体上添加Canvas Group组件,去掉Blocks Raycasts属性的勾去掉(当前组件物体下面包括当前物体的所有子物体是否接受屏幕射线检测),下面检测OnDrop事件的物体就可以正常触发了
using UnityEngine;
using UnityEngine.EventSystems;
public class Drag_4 : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
private RectTransform rectTrans;
private CanvasGroup canvasGroup;
Canvas canvas;
private void Start()
{
canvas = GameObject.Find("Canvas").GetComponent<Canvas>();
rectTrans = GetComponent<RectTransform>();
canvasGroup = GetComponent<CanvasGroup>();
}
public void OnBeginDrag(PointerEventData eventData)
{
canvasGroup.alpha = 0.5f;//拖拽得过程中降低透明度
canvasGroup.blocksRaycasts = false;//
}
public void OnEndDrag(PointerEventData eventData)
{
canvasGroup.alpha = 1f;
canvasGroup.blocksRaycasts = true;//可以继续拖拽
}
//注意如果没有OnDrag,则OnBeginDrag与OnEndDrag实现不了
public void OnDrag(PointerEventData eventData)
{
//rectTrans.anchoredPosition获取这个UI图片相对于锚点的位置信息
//eventData.delta是Vector.2结构体,表示从上一次更新,用户拖拽这个对象移动的2D位置坐标信息
//下面三种方法都可以实现图片随鼠标移动
#region 第一种 UI对象,Canvas只能是在ScreenSpace——overlay模式下
//transform.position = Input.mousePosition;
#endregion
#region 第二种 Canvas在ScreenSpace——overlay模式和ScreenSpace——camera都可以
// rectTrans.anchoredPosition += eventData.delta;
#endregion
#region 第三种 UI对象,Canvas只能是在ScreenSpace——overlay模式下
Vector2 position;
//把鼠标点击在屏幕上的点的位置(Input.mousePosition)转换为在UGUI(Canvas)上的位置(out position)
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform,
Input.mousePosition,
null,
out position);
//将转换后的position设置为UI的位置(二维向量赋值给三维向量。Z轴默认为0)
transform.localPosition = position;
#endregion
}
}
三、补充另一种拖拽UI实现方法
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class DragUI : MonoBehaviour,IPointerDownHandler,IPointerUpHandler {
public Canvas canvas;
private bool isDrag;
//鼠标点击那一刻
//鼠标点击左右中键都会执行下面的OnPointerDown方法
public void OnPointerDown(PointerEventData eventData)
{
//如果只想限制鼠标左键,或其他
//表示是鼠标左键点击的
if (eventData.button == PointerEventData.InputButton.Left)
{
isDrag = true;
}
}
//鼠标抬起那一刻
public void OnPointerUp(PointerEventData eventData)
{
isDrag = false;
}
private void Update()
{
if (isDrag)
{
//按下鼠标左键,我们就要让物品跟随鼠标
Vector2 position;
//把鼠标点击在屏幕上的点的位置(Input.mousePosition)转换为在UGUI(Canvas)上的位置(out position)
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform,
Input.mousePosition,
null,
out position);
//将转换后的position设置为UI的位置(二维向量赋值给三维向量。Z轴默认为0)
SetLocalPosition(position);
}
}
public void SetLocalPosition(Vector3 position)
{
transform.localPosition = position;
}
}