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(每次调用都重新获取,注意性能)

注意:

  • ScreenTouchPosIsTouched 只有 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

相关推荐
SunnyDays10112 小时前
C# 如何快速比较 Word 文档并显示差异
c#·对比 word 文档·比较 word 文档
天人合一peng2 小时前
Unity 3D 电脑端和手机端都实现画线与清除功能
3d·unity·智能手机
云上空2 小时前
Unity 角色“防卡墙”实战:不用动态物理材质,也能稳定解决 Wedging 问题
unity·游戏引擎·材质
不绝19113 小时前
导航系统/NavMeshAgent组件
unity
武藤一雄13 小时前
19个核心算法(C#版)
数据结构·windows·算法·c#·排序算法·.net·.netcore
不会编程的懒洋洋14 小时前
C# Task async/await CancellationToken
笔记·c#·线程·面向对象·task·同步异步
mxwin16 小时前
Unity Shader 屏幕空间 UVScreen Space UV 完全指南
unity·游戏引擎·uv
lhbian17 小时前
AI编程革命:Codex让脚本开发提速10倍
开发语言·汇编·jvm·c#
LF男男19 小时前
TouchManager
unity·c#