TouchPad(单例)

TouchPad 是一个底层触摸输入管理器,直接挂载在场景中的 UI 或游戏物体上,通过实现 Unity 事件系统接口(IPointerDownHandler, IDragHandler, IPointerUpHandler, IBeginDragHandler, IDropHandler, IPointerExitHandler)来接收原始指针事件,并将其转换为:

  • C# 事件 (供外部订阅,如 ScreenDragEvent)

  • ExecuteEvents 消息 (发送给碰撞体上的 TouchPadMessageTarget 组件)

代码解释

1.变量声明

接口名称 作用 回调方法 触发时机
IPointerDownHandler 指针按下 void OnPointerDown(PointerEventData eventData) 鼠标/手指在物体上按下时
IBeginDragHandler 开始拖拽 void OnBeginDrag(PointerEventData eventData) 按下后移动超过阈值,开始拖拽时(仅触发一次)
IDragHandler 拖拽中 void OnDrag(PointerEventData eventData) 拖拽过程中每帧触发
IPointerUpHandler 指针抬起 void OnPointerUp(PointerEventData eventData) 鼠标/手指抬起时
IDropHandler 放下 void OnDrop(PointerEventData eventData) 拖拽的物体被放到另一个可放置的物体上时
IPointerExitHandler 指针退出 void OnPointerExit(PointerEventData eventData) 指针移出物体的碰撞区域时

2.变量声明

2.1 事件声明

Action 不是 Unity 专属 ,它是 C# 内置的委托类型 ,在 Unity 中用来做事件通知、方法回调、解耦代码(最常用:按钮点击、技能释放、UI 刷新、消息广播)。

Action- C# 内置的委托类型https://blog.csdn.net/LFJINNAN/article/details/160478366

(Action = 可以存方法的变量,只能存 void 方法)

可以被外部订阅的委托字段

  • 作用:让外部脚本(如 TouchManager)订阅并接收触摸事件,而不需要通过 ExecuteEvents 机制。

TouchPadEventArgshttps://blog.csdn.net/LFJINNAN/article/details/160482722?spm=1001.2014.3001.5502

2.2 属性声明

属性 类型 说明
ScreenTouchPos Vector2 当前触摸点的屏幕坐标(私有 set)
ScreenDragDirection Vector2 计算当前拖拽方向(当前位置 - 上一帧位置)
WorldTouchPos Vector3 屏幕坐标转世界坐标,依赖 Camera.main,若相机不存在则返回 Vector3.zero
IsTouched bool 是否正在触摸中(按下后未抬起/退出)
IsActive bool 触摸处理是否启用(可通过 SetTouchActivity 修改)
CameraMain Camera 简写属性,返回 Camera.main(每次调用都重新获取,注意性能)

注意:

  • ScreenTouchPos 和 IsTouched 只有 set 没有 get? 实际上代码中是 public Vector2 ScreenTouchPos { get; private set; },所以外部可读但不可写。

  • Camera.main 每次访问都会调用 FindGameObjectsWithTag,有一定开销,但在触摸事件中调用频率较高(每帧可能多次)。可以考虑缓存。

2.3 序列化字段(Inspector 可见)

  • dlog :编辑器调试日志开关,在 UNITY_EDITOR 预处理块中使用。

  • onlyTopCollider :是否只向最顶层的碰撞体发送消息。此值会传给 tpea.SetTouch 方法,由 TouchPadEventArgs 内部实现射线检测时使用。

  • [Tooltip] : 仅作用于Inspector 面板 ,用来给变量添加鼠标悬浮提示文字

2.4 私有字段(临时变量)

字段 类型 作用
hitList List<Collider2D> 当前帧按下的碰撞体列表(或上一帧的列表)
newHitList List<Collider2D> 新一帧的碰撞体列表(实时射线检测结果)
tpea TouchPadEventArgs 复用的参数对象,减少 GC 分配
pointerID int 当前活动的指针 ID(用于多点触控过滤)
oldPosition Vector2 上一帧的屏幕坐标
2.4.1pointerID

pointerID 确保了用户拖拽哪张牌,系统就准确响应哪张牌,即使另一根手指不小心碰到屏幕也不会造成干扰。

方面 说明
核心作用 唯一标识并追踪一个特定的触摸点
主要使用场景 按下时记录,拖拽/抬起的验证,多点触控隔离
取值来源 PointerEventData.pointerId(TouchPad)或 Touch.fingerId(TouchPadS)
典型值示例 鼠标:-1 或固定值(如10);触摸第1指:0;第2指:1
不使用的后果 多点触控时状态混乱,拖拽目标错误

2.5 单例

3.单例与初始化(Awake)

单例:如果已存在实例,则销毁当前对象;否则将自己设为单例。

保证场景里 永远只能有一个该脚本对象

  • 第一次加载:赋值自己为唯一实例
  • 重复挂载 / 多复制物体:自动删掉多余的

4. 事件回调详细解析

4.1 OnPointerDown - 按下

  1. 通过 IsTouched 确保只有第一次按下被处理(防止多点触控中第二个手指触发)。

  2. 重新创建 tpea(这里产生了 GC,是潜在的优化点)。

  3. SetTouch 内部进行射线检测,填充 tpea.hits。

  4. 使用 ExecuteEvents.Execute<TouchPadMessageTarget> 向所有命中碰撞体发送 PointerDown 消息。

  5. 记录第一个命中物体的 TouchPadMessageTarget 组件到 tpea.firstSelected。

  6. 触发外部事件 ScreenPointerDownEvent。

相关推荐
kim18 分钟前
一个人 + AI,用 WinForms 搓了个 376KB 的 Windows 便签:便签 / 截图 / 标注 / OCR / 待办全塞进去了
c#
hez201032 分钟前
一行代码在 .NET 项目里启用 Satori GC
c#·.net·.net core·gc·clr
宇卿.1 小时前
C#语句:
开发语言·c#
咕白m6251 小时前
使用 C# 将 TIFF 转换为 PDF
前端·c#
JQLvopkk2 小时前
HslCommunication,一个工具测遍所有 PLC
开发语言·人工智能·c#·交互
下页、再停留2 小时前
【C#桌面客户端系列学习-7】数据查询展示
开发语言·c#·visual studio
QQ14220784493 小时前
从 C# WinForms 到 Flask + SQLite:期刊出版 XML 生成器(JATS)重构实践
sqlite·flask·c#
半亩码田4 小时前
C#转Python第4.7篇:logging:Python 的标准日志库
开发语言·python·c#
宝桥南山4 小时前
.NET 11 - 尝试创建一下AGUIServer和AGUIClient(基于新版.NET SDK for AG-UI)
microsoft·ai·微软·c#·aigc·.net
czhc11400756635 小时前
加在入口还是出口 —— 以及一个“看着像文件夹“的文件
c#