PicoVR Unity Integration SDK 3.4 常用交互API

不知道是我没找对地方,还是官方那个把这个藏的严,又或者用了什么XR的通用标砖?反正我在官方引导文档里找到的很少,不够,所以自己测试了以下几个,还算可以哦。

有需要的朋友可以看看试试呢。如果对你有帮助啊,麻烦点个赞哦。

一、先纠正核心:Pico SDK 3.4 的命名空间

3.4 已经完全重构,现在的核心命名空间是:

cs 复制代码
using UnityEngine.XR;
using Unity.XR.PXR;

之前的 Pvr_UnitySDKAPI 已经被废弃了,现在统一用 Unity.XR.PXR 下的类。

二、Pico SDK 3.4 常用 API(头盔 / 手柄 / 按键 / 摇杆)

  1. 头盔(头显)数据
cs 复制代码
// 获取 XR 头显设备
InputDevice headDevice = InputDevices.GetDeviceAtXRNode(XRNode.Head);

// 位置
if (headDevice.TryGetFeatureValue(CommonUsages.devicePosition, out Vector3 headPos))
{
    Debug.Log("头盔位置:" + headPos);
}

// 旋转
if (headDevice.TryGetFeatureValue(CommonUsages.deviceRotation, out Quaternion headRot))
{
    Debug.Log("头盔旋转:" + headRot.eulerAngles);
}
  1. 手柄(控制器)基础数据
cs 复制代码
// 左手柄
InputDevice leftController = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
// 右手柄
InputDevice rightController = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);

// 手柄位置
if (leftController.TryGetFeatureValue(CommonUsages.devicePosition, out Vector3 leftPos))
{
    Debug.Log("左手柄位置:" + leftPos);
}

// 手柄旋转
if (rightController.TryGetFeatureValue(CommonUsages.deviceRotation, out Quaternion rightRot))
{
    Debug.Log("右手柄旋转:" + rightRot.eulerAngles);
}

// 手柄是否连接
bool leftConnected = leftController.isValid;
bool rightConnected = rightController.isValid;
  1. 按键输入(3.4 用 XR 标准键位)
cs 复制代码
// 右手柄 A 键按下
if (rightController.TryGetFeatureValue(CommonUsages.primaryButton, out bool aPressed) && aPressed)
{
    Debug.Log("右手柄 A 键按下");
}

// 左手柄 X 键按下
if (leftController.TryGetFeatureValue(CommonUsages.secondaryButton, out bool xPressed) && xPressed)
{
    Debug.Log("左手柄 X 键按下");
}

// 扳机键(0~1 数值)
if (rightController.TryGetFeatureValue(CommonUsages.trigger, out float triggerValue))
{
    Debug.Log("右扳机值:" + triggerValue);
}

// 握把键
if (leftController.TryGetFeatureValue(CommonUsages.grip, out float gripValue))
{
    Debug.Log("左握把值:" + gripValue);
}
  1. 摇杆值获取(左右摇杆 XY)
cs 复制代码
// 左摇杆(移动用)
if (leftController.TryGetFeatureValue(CommonUsages.primary2DAxis, out Vector2 leftStick))
{
    Debug.Log("左摇杆:" + leftStick);
    // leftStick.x: 左右(-1~1),leftStick.y: 上下(-1~1)
}

// 右摇杆(视角用)
if (rightController.TryGetFeatureValue(CommonUsages.primary2DAxis, out Vector2 rightStick))
{
    Debug.Log("右摇杆:" + rightStick);
}

// 摇杆按下
if (leftController.TryGetFeatureValue(CommonUsages.primary2DAxisClick, out bool leftStickPressed) && leftStickPressed)
{
    Debug.Log("左摇杆按下");
}

三、3.4 专属 API(非 XR 标准,Pico 特有)

cs 复制代码
using Unity.XR.PXR;

// 获取电池电量(0~1)
float leftBattery = PXRInput.GetBatteryPercent(XRNode.LeftHand);
float rightBattery = PXRInput.GetBatteryPercent(XRNode.RightHand);

// 震动反馈(手柄震动,时长单位:秒)
PXRInput.SendHapticImpulse(XRNode.RightHand, 0.5f, 0.1f);

四、最简测试脚本(3.4 直接能用)

cs 复制代码
using UnityEngine;
using UnityEngine.XR;
using Unity.XR.PXR;

public class Pico34InputTest : MonoBehaviour
{
    private InputDevice leftController;
    private InputDevice rightController;
    private InputDevice headDevice;

    void Start()
    {
        // 获取设备
        leftController = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
        rightController = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
        headDevice = InputDevices.GetDeviceAtXRNode(XRNode.Head);
    }

    void Update()
    {
        // 头显数据
        if (headDevice.TryGetFeatureValue(CommonUsages.devicePosition, out Vector3 headPos))
        {
            Debug.Log("头盔位置:" + headPos);
        }

        // 左摇杆
        if (leftController.TryGetFeatureValue(CommonUsages.primary2DAxis, out Vector2 leftStick))
        {
            Debug.Log("左摇杆:" + leftStick);
        }

        // 右扳机
        if (rightController.TryGetFeatureValue(CommonUsages.trigger, out float trigger))
        {
            Debug.Log("右扳机值:" + trigger);
        }

        // A 键按下
        if (rightController.TryGetFeatureValue(CommonUsages.primaryButton, out bool aPressed) && aPressed)
        {
            Debug.Log("A 键按下!");
            // 震动反馈
            PXRInput.SendHapticImpulse(XRNode.RightHand, 0.5f, 0.1f);
        }
    }
}

接下来是一些安全性的判断:

一、最基础:XR 设备是否激活(必须最先判断)

cs 复制代码
using UnityEngine;
using UnityEngine.XR;

bool isXrActive = XRSettings.isDeviceActive;
Debug.Log("XR设备是否激活:" + isXrActive);
  • true = 头盔已连接、XR 正常启动、可以读头显 / 手柄数据Unity
  • false = 没插头盔、没开 XR、初始化失败 → 不要读任何手柄 / 头盔数据

二、判断「头盔(HMD)是否存在且有效」

cs 复制代码
InputDevice head = InputDevices.GetDeviceAtXRNode(XRNode.Head);
bool headOk = head.isValid; // 是否存在且可用

更严谨一点:

cs 复制代码
List<InputDevice> hmdList = new List<InputDevice>();
InputDevices.GetDevicesWithCharacteristics(InputDeviceCharacteristics.HeadMounted, hmdList);
bool hmdConnected = hmdList.Count > 0;

三、判断「头盔是否正在被追踪」(是否正常工作)

cs 复制代码
bool isTracking = false;
if (headOk)
{
    head.TryGetFeatureValue(CommonUsages.isTracked, out isTracking);
}
Debug.Log("头盔是否在追踪:" + isTracking);

摘下头盔、遮挡传感器、休眠时会变成 false

四、判断「用户是否戴着头盔」(非常实用)

cs 复制代码
bool isWorn = false;
if (headOk)
{
    head.TryGetFeatureValue(CommonUsages.userPresence, out isWorn);
}
Debug.Log("用户是否戴头盔:" + isWorn);

摘下头盔立刻 false ,戴上 true

五、手柄是否正常(左右手都可以)

cs 复制代码
InputDevice left = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
InputDevice right = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);

bool leftOk = left.isValid;
bool rightOk = right.isValid;

六、「安全读取输入」的标准写法(直接用)

cs 复制代码
using UnityEngine;
using UnityEngine.XR;
using Unity.XR.PXR;

public class PicoSafeInput : MonoBehaviour
{
    InputDevice head, left, right;

    void Start()
    {
        head = InputDevices.GetDeviceAtXRNode(XRNode.Head);
        left = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
        right = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
    }

    void Update()
    {
        // 第一步:XR 是否激活
        if (!XRSettings.isDeviceActive)
        {
            Debug.LogWarning("XR未激活,跳过输入读取");
            return;
        }

        // 第二步:头盔是否有效
        if (!head.isValid)
        {
            Debug.LogWarning("头盔无效");
            return;
        }

        // 头盔位置(只有在追踪时才读)
        if (head.TryGetFeatureValue(CommonUsages.isTracked, out bool trackOk) && trackOk)
        {
            if (head.TryGetFeatureValue(CommonUsages.devicePosition, out Vector3 pos))
            {
                // 正常使用 pos
            }
        }

        // 右手柄按键
        if (right.isValid)
        {
            if (right.TryGetFeatureValue(CommonUsages.primaryButton, out bool aPressed) && aPressed)
            {
                Debug.Log("A键按下");
            }
        }
    }
}
相关推荐
龙智DevSecOps解决方案2 小时前
3A 游戏优化技术栈:如何打通引擎级分析工具与 DevOps 持续集成管线?
unity·性能优化·游戏开发·技术美术·perforce·unrealengine
葛兰岱尔3 小时前
从 SolidWorks 到 Three.js,从 Inventor 到 Unity——制造业CAD模型“几何-语义一体化“转换,不再是天方夜谭!
开发语言·javascript·unity
世界很奇妙塔4 小时前
AR/VR产业去泡沫后:从消费端娱乐,走向产业端全域赋能
ar·vr·娱乐
鼎艺创新科技5 小时前
三维电子沙盘中OSGB倾斜摄影数据的加载与渲染
游戏引擎·cocos2d
玉夏6 小时前
【Shader基础】UV 与纹理采样 Part1
unity·着色器·uv
kyle~6 小时前
Godot开源游戏引擎
开源·游戏引擎·godot
zdr尽职尽责6 小时前
Unity录像功能
学习·ui·unity·游戏引擎
真鬼1236 小时前
【Unity Cursor】AI规矩
unity·游戏引擎
mxwin7 小时前
Unity Shader 深入理解 LinearEyeDepth 与 DepthTexture
unity·游戏引擎