开发
开发
选择平台

控制器输入和追踪概览

更新时间: 2026年2月13日
控制器为用户提供了一套熟悉的界面,用于在 Unity XR 应用中与体验内容进行互动。控制器可接收用户输入,例如按钮按下或操纵杆移动,并追踪用户的手部运动。
OVRInput 是 Meta 为 Unity 提供的统一控制器输入与追踪 API,专为 Meta Quest Touch 控制器设计。它提供一个接口,用于获取以下实时数据:
  • 控制器状态、按钮、摇杆、触发器和电容式触控
  • 手势和控制器姿态
Use Unity's Input System
对于新项目,使用 Unity 的输入系统包而非 OVRInput。OVRInput 目前仅维护用于旧版兼容功能,新增功能与新设备可能仅支持 Unity 输入系统。
如需详细了解添加基于控制器的互动的流程,例如拿取对象、在场景中移动或设置用户界面,请参阅互动 SDK 概览

设置

  1. 如要使用 OVRInput,您必须在 Unity 项目中安装 Meta XR 互动 SDK。详细步骤请参阅设置互动 SDK
  2. 然后,在场景中任意位置放置 OVRManager prefab。它负责管理设备状态与输入更新。
  3. 在处理输入或游戏逻辑的脚本中,分别在所有 UpdateFixedUpdate 方法开头,每帧调用一次 OVRInput.Update()OVRInput.FixedUpdate()。例如:
    public class XRInputManager : MonoBehaviour {
        void Update() {
            OVRInput.Update();
            // Handle input logic here
        }
        void FixedUpdate() {
            OVRInput.FixedUpdate();
            // Handle physics-based input here
        }
    }
    
    注意:调用 OVRInput 更新方法时请遵循以下最佳实践:
    • 将更新函数调用集中在一个主输入管理器脚本中,确保状态一致。
    • 在所有依赖输入状态的其他脚本之前调用更新函数。
    • 如果您的项目包含多个场景,确保每个场景中都存在该输入管理器。
  4. 引入 OVRInput 后,系统会自动添加输入绑定,定义控制器动作如何映射到 Unity。您可以在项目的 InputManager.asset 配置文件中引用这些绑定。
请参阅 OVRInput API 参考文档了解更多信息。

运作方式

以下章节介绍如何通过 OVRInput 获取控制器与追踪数据。

输入查询

OVRInput 提供了查询控制器状态的方法,包括:
  • Get():返回按钮、轴或触摸传感器的当前状态
  • GetDown():返回该按键是否在本帧被按下
  • GetUp():回该按键是否在本帧被松开
例如,以下代码检查当前帧中右控制器的触发器是否被按下:
if (OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger, OVRInput.Controller.RTouch)) {
    // Trigger pressed on right controller
}

追踪控制器姿势

OVRInput 与头戴设备在同一帧内报告控制器的姿势,相对于初始中心眼的姿势。姿势会与头戴设备同步预测,以实现低延迟渲染。
使用 OVRManager.display.RecenterPose() 可将控制器与头戴设备姿势重置到当前位置。
OVRInput 提供以下姿势追踪函数:
  • GetLocalControllerPosition():以 Vector3 返回位置
  • GetLocalControllerRotation():以 Quaternion 返回朝向

控制器标识

OVRInput 对 Meta Quest Touch 控制器使用以下标识:
  • Primary:左控制器
  • Secondary:右控制器

控制输入枚举

OVRInput 提供多种 Get() 变体,可访问不同类型的控制项,包括:
控制项枚举
OVRInput.Button
游戏手柄、控制器上的传统按键及返回键。
OVRInput.Touch
控制器上的电容感应触控面。
OVRInput.NearTouch
控制器上的接近感应触控面。
OVRInput.Axis1D
一维控制(如触发器),返回浮点状态。
OVRInput.Axis2D
二维控制(如摇杆)。返回 Vector2 状态。
第二套枚举与第一套对应,定义如下:
控制项
OVRInput.RawButton
OVRInput.RawTouch
OVRInput.RawNearTouch
OVRInput.RawAxis1D
OVRInput.RawAxis2D
第一套枚举提供虚拟化输入映射,让开发者可创建跨不同控制器类型通用的控制方案。这种虚拟映射提供了实用功能,后续章节将对此进行演示。
第二套枚举提供对控制器底层状态原始、未修改的直接访问。

按钮、触摸和接近触摸

除了传统的游戏手柄按键外,控制器还配备了电容感应控制面,这些控制面可以检测用户的手指或拇指何时进行物理接触 (Touch),以及何时处于接近状态 (NearTouch)。这可精确检测用户与特定控制面的多种不同互动状态。例如,如果用户的食指完全离开控制面,该控制对应的 NearTouch 会报告为 false。当用户的手指靠近控制面并进入其近距离范围时,在用户做出物理接触之前,NearTouch 就会报告为 true。当用户与控制面发生物理接触时,该控制对应的 Touch 会报告为 true。当用户按下食指触发器时,该控制对应的 Button 会报告为 true。这些不同的状态可用于准确检测用户与控制器的互动,并支持多种控制方案。

使用示例

以下示例演示如何查询不同输入类型(按键、摇杆、触发器、电容触摸传感器):
// returns true if the primary button (typically “A”) is currently pressed.
OVRInput.Get(OVRInput.Button.One);

// returns true if the primary button (typically “A”) was pressed this frame.
OVRInput.GetDown(OVRInput.Button.One);

// returns true if the “X” button was released this frame.
OVRInput.GetUp(OVRInput.RawButton.X);

// returns a Vector2 of the primary (typically the Left) thumbstick’s current state.
// (X/Y range of -1.0f to 1.0f)
OVRInput.Get(OVRInput.Axis2D.PrimaryThumbstick);

// returns true if the primary thumbstick is currently pressed (clicked as a button)
OVRInput.Get(OVRInput.Button.PrimaryThumbstick);

// returns true if the primary thumbstick has been moved upwards more than halfway.
// (Up/Down/Left/Right - Interpret the thumbstick as a D-pad).
OVRInput.Get(OVRInput.Button.PrimaryThumbstickUp);

// returns a float of the secondary (typically the Right) index finger trigger’s current state.
// (range of 0.0f to 1.0f)
OVRInput.Get(OVRInput.Axis1D.SecondaryIndexTrigger);

// returns a float of the left index finger trigger’s current state.
// (range of 0.0f to 1.0f)
OVRInput.Get(OVRInput.RawAxis1D.LIndexTrigger);

// returns true if the left index finger trigger has been pressed more than halfway.
// (Interpret the trigger as a button).
OVRInput.Get(OVRInput.RawButton.LIndexTrigger);

// returns true if the secondary gamepad button, typically “B”, is currently touched by the user.
OVRInput.Get(OVRInput.Touch.Two);
除指定控制项外,Get() 还接受一个可选控制器参数。支持的控制器列表见 OVRInput 的“枚举控制器”章节。
如果某控制方案仅适用于特定控制器,可显式指定控制器。如果 Get() 未传入控制器参数,默认使用 Active(当前活动)控制器,即最近产生输入的控制器。例如,用户可能先使用一对控制器,将它们放下后,再拿起一个 Xbox 控制器,在这种情况下,一旦用户使用 Xbox 控制器进行输入,当前活动控制器就会切换为该 Xbox 控制器。当前的活动控制器可通过 OVRInput.GetActiveController() 查询,而所有已连接控制器的位掩码可通过 OVRInput.GetConnectedControllers() 查询。
以下示例显式指定控制器组合以查询左右手触发器:
// returns a float of the hand trigger's current state on the left controller.
OVRInput.Get(OVRInput.Axis1D.PrimaryHandTrigger, OVRInput.Controller.Touch);

// returns a float of the hand trigger's current state on the right controller.
OVRInput.Get(OVRInput.Axis1D.SecondaryHandTrigger, OVRInput.Controller.Touch);
注意:Meta Quest Touch 控制器既可指定为组合成对的形式(通过 OVRInput.Controller.Touch),也可单独指定(通过 OVRInput.Controller.LTouchRTouch)。这一点很重要,因为指定 LTouchRTouch 时会使用另一套不同的虚拟输入映射,这套映射能让开发者更方便地编写左右手无关的输入代码。
下面的示例演示如何通过为独立控制器使用 PrimaryHandTrigger 来实现左右手无关的输入,其中 Primary 始终映射到所指定的手:
// returns a float of the hand trigger's current state on the left controller.
OVRInput.Get(OVRInput.Axis1D.PrimaryHandTrigger, OVRInput.Controller.LTouch);

// returns a float of the hand trigger's current state on the right controller.
OVRInput.Get(OVRInput.Axis1D.PrimaryHandTrigger, OVRInput.Controller.RTouch);
这种方法可以进行扩展,通过将控制器赋值给一个可在外部设置的变量(例如公有变量),让同一段代码同时适用于左手和右手。
以下示例通过将控制器暴露为可配置变量,编写可复用输入代码:
// public variable that can be set to LTouch or RTouch in the Unity Inspector
public OVRInput.Controller controller;

// returns a float of the hand trigger’s current state on the controller
// specified by the controller variable.
OVRInput.Get(OVRInput.Axis1D.PrimaryHandTrigger, controller);

// returns true if the primary button (“A” or “X”) is pressed on the controller
// specified by the controller variable.
OVRInput.Get(OVRInput.Button.One, controller);
这就避免了为区分左手或右手输入映射而编写大量 if/else 判断的常规写法。

Touch 输入映射

下图展示控制器常用输入映射。更多可用映射请参阅 OVRInput API 参考文档。

组合控制器虚拟映射

通过 OVRInput.Controller.Touch 以组合方式访问控制器时,虚拟映射与左右手分离的标准游戏手柄布局高度一致。
Combined controller mapping diagram

独立控制器虚拟映射

通过 OVRInput.Controller.LTouchOVRInput.Controller.RTouch 单独访问左/右控制器时,虚拟映射会切换为左右手无关的输入绑定。例如:同一脚本可根据挂载的左右手动态查询对应控制器,Button.One 会自动映射为 A 键或 X 键。
Individual controller mapping diagram

原始映射

原始映射会直接暴露控制器的原生状态。控制器的布局与左右手分离的标准游戏手柄布局高度一致。
Raw controller mapping diagram

详细了解

若要详细了解在 Unity 的 XR 应用程序中使用控制器的信息,请参阅以下指南:

设计指南

  • 输入模式:了解不同的输入模式。
  • 头部:了解关于使用头部输入的设计和用户体验最佳实践。
  • 手势:了解关于使用手势的设计和用户体验最佳实践。
  • 控制器:了解关于使用控制器的设计和用户体验最佳实践。
  • 语音:了解关于使用语音的设计和用户体验最佳实践。
  • 外围设备:了解关于使用外围设备的设计和用户体验最佳实践。