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

相关推荐
雨落倾城夏未凉1 天前
第四章c#方法-参数数组和可选参数(16)
后端·c#
唐青枫2 天前
线程不是越多越快:C#.NET Thread 生命周期、同步与后台工作线程实战
c#·.net
唐青枫3 天前
别只会反射:C#.NET Emit 动态生成代码实战详解
c#·.net
咕白m6254 天前
.NET 环境下 Word 超链接批量提取方案
c#·.net
用户91721561902114 天前
C# 通信协议增量解析:用状态机处理半包和粘包
c#
小码编匠4 天前
C# 工控上位机必备:数据转换工具类与十个核心模块
后端·c#·.net
唐青枫6 天前
别再乱用 StartNew:C#.NET TaskFactory 任务调度实战详解
c#·.net
Artech7 天前
[MAF预定义的AIContextProvider-03]ChatHistoryMemoryProvider——赋予Agent从经验中学习的能力
ai·c#·agent·memory·maf
Scout-leaf8 天前
C#摸鱼实录——IoC与DI案例详解
c#
咕白m6258 天前
使用 C# 在 Excel 中应用多种字体样式
后端·c#