You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否通过脚本选中并移动动态实例化的On-Screen Stick摇杆

动态生成的On-Screen Stick无法响应触发触摸的解决方法

问题场景

  • 实现逻辑:检测到屏幕触摸时,动态实例化挂载On-Screen Stick组件的摇杆预制体,对应手指抬起时销毁该摇杆实例
  • 故障表现:实例化后的摇杆无法正常拖动,手动调用ExecuteEvents.Execute触发Select事件无任何效果

故障原因

Unity内置的On-Screen Stick组件是基于UGUI指针事件系统实现交互,依赖IPointerDownHandler、IDragHandler、IPointerUpHandler三个接口响应输入。
你在触摸已经产生后才实例化摇杆,这根手指的PointerDown事件已经完成派发,新生成的摇杆实例根本没收到初始按下的信号,自然不会绑定这根手指的后续拖动、抬起输入。你之前调用Select事件完全无效,因为On-Screen Stick本身就没有实现选中事件的处理逻辑,属于触发了不相关的事件。


修复步骤

核心逻辑是:摇杆实例化完成后,手动给它传入当前触发创建操作的手指的指针数据,模拟它收到了PointerDown事件,后续事件系统会自动把这根手指的所有后续输入派发给该摇杆。

  1. 传入正确的手指ID,这是多触摸场景下识别对应手指的核心参数,不要用空的BaseEventData,要使用PointerEventData承载触摸信息
  2. 主动给摇杆派发PointerDown事件,而非Select事件
  3. 销毁摇杆前手动补派发PointerUp事件,避免事件系统残留指针捕获状态导致输入异常

参考实现代码:

// 检测到有效触摸、完成摇杆实例化后执行
OnScreenStick stickComponent = leftJoyStick.GetComponent<OnScreenStick>();
// 基于当前触摸数据构造指针事件
PointerEventData touchEventData = new PointerEventData(EventSystem.current)
{
    pointerId = currentTouch.fingerId, // 绑定触发创建的那根手指的ID
    position = currentTouch.position,
    pressPosition = currentTouch.position,
    eligibleForClick = true,
    pointerPress = stickComponent.gameObject
};
// 手动触发摇杆的PointerDown逻辑,捕获该手指输入
ExecuteEvents.Execute(stickComponent.gameObject, touchEventData, ExecuteEvents.pointerDownHandler);

// --- 手指抬起、准备销毁摇杆前执行 ---
// 手动触发PointerUp,清理事件系统状态
ExecuteEvents.Execute(stickComponent.gameObject, touchEventData, ExecuteEvents.pointerUpHandler);
Destroy(leftJoyStick);

注意事项

  • 实例化摇杆时要将其RectTransform定位到当前触摸的屏幕坐标位置,避免初始位置偏移导致摇杆输入值异常
  • 确保生成的摇杆节点在UI层级的最上方,不会被其他带Raycast Target的UI元素遮挡,否则后续拖动事件会被拦截
  • 不要随意修改On-Screen Stick组件的Movement Range等默认参数,除非你明确知道参数效果,否则容易出现拖动范围异常问题

内容的提问来源于stack exchange,提问作者Ronny Bigler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 23:30:09