Unity用鼠标拖拽UI,UI跟随鼠标移动
- 效果
- 一、原理
- 二、源码
- 总结
- 💢💢版权声明
效果
先上效果
一、原理
继承几个拖拽的接口 IBeginDragHandler, IDragHandler,IEndDragHandler
计算下偏移量,转换下坐标系
限制下可拖拽的范围,我设置的是canvas的大小
二、源码
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.EventSystems;
namespace HHQ
{
/// <summary>
/// 拖拽ui(限制拖拽范围)
/// </summary>
public class LimitUIDrag : MonoBehaviour, IBeginDragHandler, IDragHandler,IEndDragHandler
{
/// <summary>
/// 限制的区域
/// </summary>
private RectTransform limitContainer;
private Canvas canvas;
private RectTransform rt;
// 位置偏移量
Vector3 offset = Vector3.zero;
// 最小、最大X、Y坐标
float minX, maxX, minY, maxY;
void Start()
{
rt = GetComponent<RectTransform>();
canvas = GetComponentInParent<Canvas>();
limitContainer = canvas.GetComponent<RectTransform>();
}
/// <summary>
/// 开始拖拽
/// </summary>
/// <param name="eventData"></param>
public void OnBeginDrag(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
return;
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.enterEventCamera, out Vector3 globalMousePos))
{
// 计算偏移量
offset = rt.position - globalMousePos;
// 设置拖拽范围
SetDragRange();
//EventDispatcher.GameEvent.DispatchEvent(101);
}
}
/// <summary>
/// 拖拽中
/// </summary>
/// <param name="eventData"></param>
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);
}
}
/// <summary>
/// 拖拽结束
/// </summary>
/// <param name="eventData"></param>
/// <exception cref="NotImplementedException"></exception>
public void OnEndDrag(PointerEventData eventData)
{
//EventDispatcher.GameEvent.DispatchEvent(103);
}
// 设置最大、最小坐标
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;
}
}
}
总结
欢迎大佬多多来给萌新指正,欢迎大家来共同探讨。
如果各位看官觉得文章有点点帮助,跪求各位给点个“一键三连”,谢啦~
声明:本博文章若非特殊注明皆为原创原文链接
https://blog.csdn.net/Wrinkle2017/article/details/130885091
————————————————————————————————
💢💢版权声明
版权声明:本博客为非营利性个人原创
所刊登的所有作品的著作权均为本人所拥有
本人保留所有法定权利,违者必究!
对于需要复制、转载、链接和传播博客文章或内容的
请及时和本博主进行联系
对于经本博主明确授权和许可使用文章及内容的
使用时请注明文章或内容出处并注明网址
转载请附上原文出处链接及本声明