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

Unity EnhancedTouch全屏玩家控制器如何避免UI按钮输入冲突?

解决UI触摸与虚拟摇杆冲突的几种实用方法

方法1:通过EventSystem直接判断触摸是否命中UI

这是最通用的方案,每次触摸触发时先检查触点是否落在UI元素上,是则跳过摇杆逻辑。

代码示例:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem.EnhancedTouch;

public class JoystickController : MonoBehaviour
{
    private void OnEnable()
    {
        TouchSimulation.Enable();
        EnhancedTouchSupport.Enable();
        Touch.onFingerDown += HandleFingerDown;
    }

    private void OnDisable()
    {
        Touch.onFingerDown -= HandleFingerDown;
        EnhancedTouchSupport.Disable();
        TouchSimulation.Disable();
    }

    private void HandleFingerDown(Finger finger)
    {
        Vector2 screenPos = finger.screenPosition;
        // 真实设备用带索引的重载,编辑器模拟触摸可直接用IsPointerOverGameObject()
        if (EventSystem.current.IsPointerOverGameObject(finger.index))
        {
            // 触摸点在UI上,不触发摇杆
            return;
        }

        // 执行虚拟摇杆创建逻辑
        SpawnVirtualJoystick(screenPos);
    }

    private void SpawnVirtualJoystick(Vector2 spawnPos)
    {
        // 你的摇杆生成代码
    }
}

方法2:给UI添加触摸拦截标记

给需要拦截的UI元素(Button、Slider等)挂载一个简单脚本,标记当前触摸是否被UI占用,摇杆逻辑读取该标记判断是否响应。

拦截脚本:

using UnityEngine;
using UnityEngine.EventSystems;

public class UITouchBlocker : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    public static bool IsTouchOnUI { get; private set; }

    public void OnPointerDown(PointerEventData eventData)
    {
        IsTouchOnUI = true;
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        IsTouchOnUI = false;
    }

    private void OnDisable()
    {
        IsTouchOnUI = false;
    }
}

摇杆逻辑中判断:

private void HandleFingerDown(Finger finger)
{
    if (UITouchBlocker.IsTouchOnUI) return;
    // 创建摇杆逻辑
}

这种方式适合需要自定义拦截规则的场景,比如部分UI只拦截按下动作,不拦截拖动。

方法3:固定屏幕区域划分

如果UI位置固定(比如暂停按钮在右上角),可以直接判断触摸点是否在UI专属区域内,不在则触发摇杆。

示例:

private void HandleFingerDown(Finger finger)
{
    Vector2 screenPos = finger.screenPosition;
    // 定义UI拦截区域(右上角100x100范围)
    Rect uiBlockArea = new Rect(Screen.width - 100, Screen.height - 100, 100, 100);
    if (uiBlockArea.Contains(screenPos)) return;
    
    // 创建摇杆逻辑
}

这种方法最简单,但仅适用于UI位置完全固定的场景。

方法4:利用输入系统优先级设置

如果使用Unity新输入系统,可以在输入动作的设置中,让UI Input Module优先捕获触摸输入,这样UI元素会先响应触摸,摇杆不会接收到被UI拦截的输入信号。


内容的提问来源于stack exchange,提问作者Santiago Rodríguez Eidner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:53:13