using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class Drag : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler, ICanvasRaycastFilter
{
private Transform nowparent;//记录原始坐标位置
private bool isRaycastLocationValid = true;//默认射线不能穿透物体
public Transform IconList;
///
/// 开始拖拽
///
public void OnBeginDrag(PointerEventData eventData)
{
this.transform.SetAsLastSibling();
//1.SetAsFirstSibling();
//2.SetAsLastSibling();
//3.SetSiblingIndex(n)
//SetAsFirstSibling()是设置为最先渲染的,即会被后渲染的挡住。
//SetAsLastSibling();是设置为最后渲染的,即会挡住比他先渲染的
//SetSiblingIndex(n)是设置层级,从0开始到childcount -1
//当n为0时,其效果与SetAsFirstSibling();相同
//但是当层级小于0时,其效果与SetAsLastSibling()一致
//当层级为大于等于transform.parent.childCount - 1时,其效果与SetAsLastSibling一致
nowparent =this.transform.parent;//初始位置
isRaycastLocationValid = false;//设置为可以穿透
transform.SetParent(IconList);//将当前拖拽的物品放在最外层下 效果:可以挡住随意UI 避免呗其他UI挡住
}
///
/// UI跟随 鼠标
///
///
public void OnDrag(PointerEventData eventData)
{
transform.position = Input.mousePosition;
}
///
/// 拖拽结束
///
public void OnEndDrag(PointerEventData eventData)
{
//获取鼠标终点位置可能存在的物品
GameObject go = eventData.pointerCurrentRaycast.gameObject;
if (go != null)//落点位置不为空
{
Debug.Log(go.name);//打印一下落点位置名称
if (go.tag == ("Gird"))//鼠标终点位置是空格子
{
Debug.Log("空格子");
SetParentAndPosition(transform, go.transform);
}
else if (go.tag == transform.tag)//标签相同 放回
{
//将拖拽的物品1放到鼠标终点下的位置
SetParentAndPosition(transform, go.transform);
}
else//无效位置,物品回到原来的位置
{
SetParentAndPosition(transform, nowparent);
}
}
else
{
SetParentAndPosition(transform, nowparent);
}
isRaycastLocationValid = true;//射线不可以穿透物体
}
// 将child放到parent下做其子物体
private void SetParentAndPosition(Transform child, Transform parent)
{
child.SetParent(parent);
child.position = parent.position;//子物体的坐标跟随父物体
}
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
{
return isRaycastLocationValid;
}
}
2.鼠标拖动UI并限制拖动区域(参考地址:Unity UI拖拽及拖拽范围限制功能的实现_疯狂的窝瓜的博客-CSDN博客)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class DragItme : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
[Header("表示限制的区域")]
public RectTransform LimitContainer;
[Header("场景中Canvas")]
public Canvas canvas;
RectTransform rt;
// 位置偏移量
Vector3 offset = Vector3.zero;
// 最小、最大X、Y坐标
float minX, maxX, minY, maxY;
public GameObject itme;
public Transform tr;
public Toggle ThisToggle;
void Start()
{
rt = GetComponent();
}
void Update()
{
if ( ThisToggle.isOn)
{
// Debug.Log("name=" + this.gameObject.name);
}
if (Input.GetKey(KeyCode.Delete)&& ThisToggle.isOn)
{
Debug.Log("name=" + this.gameObject.name);
Destroy(this.gameObject);
}
}
///
/// 开始拖拽
///
///
public void OnBeginDrag(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
return;
//var go= GameObject.Instantiate(itme, tr);
//go.name = "DragItme";
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.enterEventCamera, out Vector3 globalMousePos))
{
// 计算偏移量
offset = rt.position - globalMousePos;
// 设置拖拽范围
SetDragRange();
}
}
///
/// 创建UI
///
///
///
public static GameObject CreationUI(string name, Transform uILayer)
{
Debug.Log("创建UI " + name);
var tempObject = Resources.Load("prefab/UI/" + name) as GameObject;
GameObject.Instantiate(tempObject, uILayer);
return tempObject;
}
///
/// 拖拽中
///
///
public void OnDrag(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
return;
// 将屏幕空间上的点转换为位于给定RectTransform平面上的世界空间中的位置
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.pressEventCamera, out Vector3 globalMousePos))
{
rt.position = DragRangeLimit(globalMousePos + offset);
}
}
///
/// 拖拽结束
///
public void OnEndDrag(PointerEventData eventData)
{
this.transform.GetComponent().isOn = false;
Debug.Log("name=" + this.name);
}
///
/// 设置最大、最小坐标
///
void SetDragRange()
{
// 最小x坐标 = 容器当前x坐标 - 容器轴心距离左边界的距离 + UI轴心距离左边界的距离
minX = LimitContainer.position.x
- LimitContainer.pivot.x * LimitContainer.rect.width * canvas.scaleFactor
+ rt.rect.width * canvas.scaleFactor * rt.pivot.x;
// 最大x坐标 = 容器当前x坐标 + 容器轴心距离右边界的距离 - UI轴心距离右边界的距离
maxX = LimitContainer.position.x
+ (1 - LimitContainer.pivot.x) * LimitContainer.rect.width * canvas.scaleFactor
- rt.rect.width * canvas.scaleFactor * (1 - rt.pivot.x);
// 最小y坐标 = 容器当前y坐标 - 容器轴心距离底边的距离 + UI轴心距离底边的距离
minY = LimitContainer.position.y
- LimitContainer.pivot.y * LimitContainer.rect.height * canvas.scaleFactor
+ rt.rect.height * canvas.scaleFactor * rt.pivot.y;
// 最大y坐标 = 容器当前x坐标 + 容器轴心距离顶边的距离 - UI轴心距离顶边的距离
maxY = LimitContainer.position.y
+ (1 - LimitContainer.pivot.y) * LimitContainer.rect.height * canvas.scaleFactor
- rt.rect.height * canvas.scaleFactor * (1 - rt.pivot.y);
}
///
/// 限制坐标范围
///
///
///
Vector3 DragRangeLimit(Vector3 pos)
{
pos.x = Mathf.Clamp(pos.x, minX, maxX);
pos.y = Mathf.Clamp(pos.y, minY, maxY);
return pos;
}
}