Unity用鼠标拖拽UI,UI跟随鼠标移动
效果
先上效果
一、原理
继承几个拖拽的接口 IBeginDragHandler, IDragHandler,IEndDragHandler
计算下偏移量,转换下坐标系
限制下可拖拽的范围,我设置的是canvas的大小
二、源码
usingSystem.Collections;usingSystem.Collections.Generic;usingUnity.VisualScripting;usingUnityEngine;usingUnityEngine.EventSystems;namespaceHHQ{/// <summary>/// 拖拽ui(限制拖拽范围)/// </summary>publicclassLimitUIDrag:MonoBehaviour,IBeginDragHandler,IDragHandler,IEndDragHandler{/// <summary>/// 限制的区域/// </summary>privateRectTransform limitContainer;privateCanvas canvas;privateRectTransform rt;// 位置偏移量Vector3 offset = Vector3.zero;// 最小、最大X、Y坐标float minX, maxX, minY, maxY;voidStart(){
rt =GetComponent<RectTransform>();
canvas =GetComponentInParent<Canvas>();
limitContainer = canvas.GetComponent<RectTransform>();}/// <summary>/// 开始拖拽/// </summary>/// <param name="eventData"></param>publicvoidOnBeginDrag(PointerEventData eventData){if(eventData.button != PointerEventData.InputButton.Left)return;if(RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.enterEventCamera,outVector3 globalMousePos)){// 计算偏移量
offset = rt.position - globalMousePos;// 设置拖拽范围SetDragRange();//EventDispatcher.GameEvent.DispatchEvent(101);}}/// <summary>/// 拖拽中/// </summary>/// <param name="eventData"></param>publicvoidOnDrag(PointerEventData eventData){if(eventData.button != PointerEventData.InputButton.Left)return;// 将屏幕空间上的点转换为位于给定RectTransform平面上的世界空间中的位置if(RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.pressEventCamera,outVector3 globalMousePos)){
rt.position =DragRangeLimit(globalMousePos + offset);}}/// <summary>/// 拖拽结束/// </summary>/// <param name="eventData"></param>/// <exception cref="NotImplementedException"></exception>publicvoidOnEndDrag(PointerEventData eventData){//EventDispatcher.GameEvent.DispatchEvent(103);}// 设置最大、最小坐标voidSetDragRange(){// 最小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);}// 限制坐标范围Vector3DragRangeLimit(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
————————————————————————————————
💢💢版权声明
版权声明:本博客为非营利性个人原创
所刊登的所有作品的著作权均为本人所拥有
本人保留所有法定权利,违者必究!
对于需要复制、转载、链接和传播博客文章或内容的
请及时和本博主进行联系
对于经本博主明确授权和许可使用文章及内容的
使用时请注明文章或内容出处并注明网址
转载请附上原文出处链接及本声明
版权归原作者 水光涵月 所有, 如有侵权,请联系我们删除。