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

如何在Three.js WebXR中获取HTC Vive控制器触摸板信息并移动物体

在Three.js WebXR中实现HTC Vive触摸板移动物体

WebXR触摸板支持现状

目前WebXR已完全支持HTC Vive控制器的触摸板输入,包括触摸状态与轴数据获取,2020年的限制早已被移除,你可以正常实现触摸板控制逻辑。

替代WebVR代码的WebXR实现方案

在Three.js的WebXR生态中,控制器输入通过Gamepad对象与相关事件处理,以下是对应你原有WebVR逻辑的实现代码:

let controller1;
let group; // 需移动的目标物体组
let isTriggerPressed = false;
let isThumbpadTouched = false;

// 初始化控制器
function initControllers() {
  controller1 = renderer.xr.getController(0);
  controller1.addEventListener('connected', (event) => {
    controller1.add(buildController(event.data));
  });
  controller1.addEventListener('disconnected', () => {
    controller1.remove(controller1.children[0]);
  });
  scene.add(controller1);

  // 监听扳机按压/释放状态
  controller1.addEventListener('selectstart', () => {
    isTriggerPressed = true;
  });
  controller1.addEventListener('selectend', () => {
    isTriggerPressed = false;
  });
}

// 构建控制器可视化模型(可选)
function buildController(data) {
  let geometry, material;
  switch (data.targetRayMode) {
    case 'tracked-pointer':
      geometry = new THREE.BufferGeometry();
      geometry.setAttribute('position', new THREE.Float32BufferAttribute([0, 0, 0, 0, 0, -1], 3));
      geometry.setAttribute('color', new THREE.Float32BufferAttribute([1, 1, 1, 0.5, 0.5, 0.5], 3));
      material = new THREE.LineBasicMaterial({ vertexColors: true, blending: THREE.AdditiveBlending });
      return new THREE.Line(geometry, material);
    default:
      geometry = new THREE.CylinderGeometry(0.03, 0.03, 0.1, 6);
      geometry.translate(0, -0.05, 0);
      material = new THREE.MeshStandardMaterial({ color: 0xffffff });
      return new THREE.Mesh(geometry, material);
  }
}

// 在动画循环中处理触摸板输入
function animate() {
  renderer.setAnimationLoop(() => {
    render();
    updateControllerInput();
  });
}

function updateControllerInput() {
  const gamepad = controller1.userData.gamepad;
  if (!gamepad) return;

  // 获取触摸板触摸状态(HTC Vive触摸板对应buttons[2])
  isThumbpadTouched = gamepad.buttons[2].touched;

  if (isThumbpadTouched) {
    // 获取触摸板轴数据:axes[0]为X轴(左-1/右1),axes[1]为Y轴(下-1/上1)
    const xAxis = gamepad.axes[0];
    const yAxis = gamepad.axes[1];

    if (!isTriggerPressed) {
      // 仅触摸板:移动X、Z轴
      group.position.x += xAxis * 0.1; // 调整系数控制移动速度
      group.position.z += yAxis * 0.1;
    } else {
      // 触摸板+扳机:移动Y轴
      group.position.y += -yAxis * 0.1;
    }
  }
}

关键细节说明

  • HTC Vive控制器按钮索引:buttons[0]为扳机,buttons[1]为握把键,buttons[2]为触摸板(包含touched状态与轴数据)
  • 轴数据范围均为-1到1,可根据需求调整移动方向与速度系数
  • 用gamepad.buttons[2].touched替代WebVR中getButtonState('thumbpad')的触摸判断
  • 扳机状态通过selectstart/selectend事件监听,对应WebVR中getButtonState('trigger')的逻辑

内容的提问来源于stack exchange,提问作者謝辰浩

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:20:26