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

移动端WebGL轨道相机触屏跳转问题求助及代码排查

修复移动端WebGL轨道相机UI干扰后跳转问题

问题本质

按住UI元素时,该触摸会被UI系统捕获,但如果相机脚本仍在追踪所有触摸输入,当抬起UI手指后,相机脚本会错误地将剩余的滑动手指当作新的触摸起点,导致位置/旋转计算出现突变,引发跳转。

具体修复方案

1. 过滤被UI捕获的触摸

在相机脚本中,每次处理触摸前先判断该触摸是否被UI元素接收,仅处理未被UI捕获的触摸:

private bool IsTouchOverUI(Touch touch)
{
    // 基础UI触摸判断
    if (EventSystem.current.IsPointerOverGameObject(touch.fingerId))
    {
        return true;
    }
    // WebGL下补充射线检测,修复原生方法的判断偏差
    PointerEventData pointerData = new PointerEventData(EventSystem.current);
    pointerData.position = new Vector2(touch.position.x, touch.position.y);
    List<RaycastResult> hitResults = new List<RaycastResult>();
    EventSystem.current.RaycastAll(pointerData, hitResults);
    return hitResults.Count > 0;
}

2. 单独维护相机控制的触摸列表

不要直接遍历Input.touches,自己维护一个仅包含用于相机控制的触摸列表,确保只追踪未触碰UI的触摸:

private List<Touch> _cameraControlTouches = new List<Touch>();
private int _prevTouchCount = 0;

private void Update()
{
    _cameraControlTouches.Clear();
    foreach (Touch touch in Input.touches)
    {
        if (!IsTouchOverUI(touch))
        {
            _cameraControlTouches.Add(touch);
        }
    }

    // 基于过滤后的列表处理相机逻辑
    if (_cameraControlTouches.Count == 1)
    {
        HandleSingleTouchRotation();
    }
    else if (_cameraControlTouches.Count == 2)
    {
        HandleTwoTouchZoom();
    }

    _prevTouchCount = _cameraControlTouches.Count;
}

3. 触摸数量变化时添加平滑过渡

当触摸数量从2变为1(即抬起UI手指的场景),记录当前相机状态,将新触摸的起点初始化为当前屏幕位置,避免计算差值时出现跳变:

private Vector2 _lastSingleTouchPos;
private Vector3 _currentCamRotation;
private bool _skipFirstDelta = false;

private void HandleSingleTouchRotation()
{
    Touch touch = _cameraControlTouches[0];
    if (_skipFirstDelta)
    {
        _lastSingleTouchPos = touch.position;
        _skipFirstDelta = false;
        return;
    }

    Vector2 delta = touch.position - _lastSingleTouchPos;
    _currentCamRotation += new Vector3(-delta.y * 0.1f, delta.x * 0.1f, 0);
    transform.eulerAngles = _currentCamRotation;
    _lastSingleTouchPos = touch.position;
}

private void Update()
{
    // ... 前面的触摸过滤逻辑 ...
    if (_prevTouchCount == 2 && _cameraControlTouches.Count == 1)
    {
        _skipFirstDelta = true;
        _currentCamRotation = transform.eulerAngles;
    }
}

4. WebGL专属优化

  • 仅给需要交互的UI元素勾选Raycast Target,避免全屏空白Panel这类元素意外捕获触摸
  • 关闭相机组件的Use GUI选项(若存在),防止相机输入被UI系统干扰

验证流程

  1. 按住任意UI元素,相机无任何响应
  2. 另一手指在空白区域滑动,相机正常执行轨道控制
  3. 抬起UI上的手指,相机保持当前状态,无跳转现象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:10:13