当前位置: 首页 > news >正文

Unity UGUI 拖拽组件

效果展示

在这里插入图片描述

使用方式

拖到图片上即可用

父节点会约束它的活动范围哦~
父节点会约束它的活动范围哦~
父节点会约束它的活动范围哦~

在这里插入图片描述

源码


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;/// <summary>
/// UI DragComponent 
/// 
/// Easy ui drag and drop
/// 
/// Easy~~~
/// 
/// @anchor ChenJC
/// @time: 2023/02/28
/// </summary>
public class DragComponent : MonoBehaviour, IBeginDragHandler, IDragHandler, IDropHandler
{RectTransform rectTransform, parentRectTrans;float minX, minY, maxX, maxY;Vector2 offset;public delegate void DragHandlerEvent( Vector2 currentPos );public DragHandlerEvent dragBeginEvent;public DragHandlerEvent dragEvent;public DragHandlerEvent dropEvent;#region Monobehavior Methodsprivate void Awake(){parentRectTrans = transform.parent as RectTransform;rectTransform = transform as RectTransform;}private void Start(){var parentAnchorX = parentRectTrans.pivot.x * parentRectTrans.rect.width;var parentAnchorY = parentRectTrans.pivot.y * parentRectTrans.rect.height;minX = rectTransform.rect.width * 0.5f - parentAnchorX;minY = rectTransform.rect.height * 0.5f - parentAnchorY;maxX = parentRectTrans.rect.width - rectTransform.rect.width * 0.5f - parentAnchorX;maxY = parentRectTrans.rect.height - rectTransform.rect.height * 0.5f - parentAnchorY;}#endregion#region Internal Methodsprivate Vector2 ConstraintWithinParentNode( Vector2 pos ){pos.x = Mathf.Clamp( pos.x, minX, maxX );pos.y = Mathf.Clamp( pos.y, minY, maxY );return pos;}private bool Convert2local( Vector2 screenPos, out Vector2 localPos, Camera camera ){return RectTransformUtility.ScreenPointToLocalPointInRectangle( parentRectTrans, screenPos, camera, out localPos );}#endregion#region Drag Handler Methodspublic void OnBeginDrag( PointerEventData eventData ){Vector2 localPos;if ( Convert2local( eventData.position, out localPos, eventData.pressEventCamera ) ){Vector2 src = rectTransform.localPosition;offset = src - localPos;dragBeginEvent?.Invoke( src );}}public void OnDrag( PointerEventData eventData ){Vector2 localPos;if ( Convert2local( eventData.position, out localPos, eventData.pressEventCamera ) ){Vector2 dest = ConstraintWithinParentNode( localPos + offset );rectTransform.localPosition = dest;dragEvent?.Invoke( dest );}}public void OnDrop( PointerEventData eventData ){Vector2 localPos;if ( Convert2local( eventData.position, out localPos, eventData.pressEventCamera ) ){Vector2 dest = ConstraintWithinParentNode( localPos + offset );rectTransform.localPosition = dest;dropEvent?.Invoke( dest );}}#endregion
}

拖拽事件监听

依次 开始拖拽时触发; 拖拽过程中持续触发; 拖拽结束时触发
在这里插入图片描述

原理介绍

在这里插入图片描述

开始拖拽的时候

offset = sub.localtionPos - p.localtionPos

通过计算鼠标点 计算出 相对于图片原点的 偏移 并缓存

  public void OnBeginDrag( PointerEventData eventData ){Vector2 localPos;if ( Convert2local( eventData.position, out localPos, eventData.pressEventCamera ) ){Vector2 src = rectTransform.localPosition;offset = src - localPos;dragBeginEvent?.Invoke( src );}}

拖拽过程中 我们加上这个偏移向量 就能得到相对偏移的拖拽方式

sub.locationsPos = p.locationPos + offset

public void OnDrag( PointerEventData eventData ){Vector2 localPos;if ( Convert2local( eventData.position, out localPos, eventData.pressEventCamera ) ){Vector2 dest = ConstraintWithinParentNode( localPos + offset );rectTransform.localPosition = dest;dragEvent?.Invoke( dest );}}

限制活动范围 保持在父节点以内活动

示意图

在这里插入图片描述

如图可以知道 最小X 等于自身宽 的一半 同时要减去父节点 宽的一半
可以知道 最小Y 等于自身高 的一半 同时要减去父节点 高的一半

最大值 是父节点一半 - 自身大小的一半 在Unity里 你可以通过 pivot 来获取 图片锚点相对于图片自身size的百分比值 ( 0~1)

计算出最小X,最小Y,最大X,最大Y

  private void Start(){var parentAnchorX = parentRectTrans.pivot.x * parentRectTrans.rect.width;var parentAnchorY = parentRectTrans.pivot.y * parentRectTrans.rect.height;minX = rectTransform.rect.width * 0.5f - parentAnchorX;minY = rectTransform.rect.height * 0.5f - parentAnchorY;maxX = parentRectTrans.rect.width - rectTransform.rect.width * 0.5f - parentAnchorX;maxY = parentRectTrans.rect.height - rectTransform.rect.height * 0.5f - parentAnchorY;}

新的位置约束在范围内

在这里插入图片描述

   private Vector2 ConstraintWithinParentNode( Vector2 pos ){pos.x = Mathf.Clamp( pos.x, minX, maxX );pos.y = Mathf.Clamp( pos.y, minY, maxY );return pos;}
http://www.lryc.cn/news/23952.html

相关文章:

  • 面试总结——react生命周期
  • 初探推荐系统-01
  • html实现浪漫的爱情日记(附源码)
  • detectron2容器环境安装问题(1)
  • JAVA线程池原理详解二
  • Java 常用 API
  • 记一次分布式环境下TOKEN实现用户登录
  • 用cpolar发布本地的论坛网站 1
  • CSS的4种引入方式
  • Shell高级——Linux中的文件描述符(本质是数组的下标)
  • Nvidia jetson nano硬件架构
  • ffmpeg多路同时推流
  • 一次性搞定 `SHOW SLAVE STATUS` 的解读
  • 【代码随想录训练营】【Day25】第七章|回溯算法 |216.组合总和III|17.电话号码的字母组合
  • docker使用
  • 手把手docker registry配置登录名/密码
  • 一步打通多渠道服务场景 中电金信源启移动开发平台MADP功能“上新”
  • Kubernetes06:Controller (Deployment无状态应用)
  • 低代码开发平台选型必看指南
  • OVN:ovn20.03.1/ovs2.13.0编译rpm过程
  • Shell管道
  • Zynq UltraScale系列使用MIPI CSI-2 RX Subsystem 解码MIPI视频PD输出 提供2套工程源码和技术支持
  • C++:详解C++11 线程休眠函数
  • TryHackMe-The Great Escape(Docker)
  • 这么强才给我28k,我头都不回,转身拿下40k~
  • 【Python学习笔记】第二十一节 Python Lambda 函数
  • Nginx学习整理
  • 阿里面试之Hr面,这个套路把我坑惨了......
  • 域基础和基本环境搭建
  • Java Map集合体系(HashMap、LinkedHashMap、TreeMap、集合嵌套)