【unity】Pico VR 开发笔记(基础篇)

Pico VR 开发笔记(基础篇)

XR Interaction Tooikit 版本 2.3.2

一、环境搭建

其实官方文档已经写的很详细了,这里只是不废话快速搭建,另外有一项官方说明有误的,补充说明一下,在开发工具部分说明

插件安装——安装pico的sdk和XR Interaction Tooikit

环境配置——在场景里添加头显和手柄,并进行配置和项目配置

开发工具——Pico提供的串流开发工具,可以在不打包的情况的,使用手柄和头显进行调试。

1、插件安装

pico SDK安装

pico SDK下载地址:SDK - PICO 开发者平台 (pico-interactive.com)

SDK下载后解压

打开unity→Window→PackgeManager→Add Package From disk(左上角+)→选择解压后文件里的package.json

XR Interaction Tooikit安装

在packgeManager里搜索XR Interaction Tooikit

选择版本尽量高版本,不要低于2.1.0。

打开Samples 面板,导入 Starter Assets、**XR Device Simulater **和 Tunneling Vignette

2、环境配置

场景配置

添加XR Origin:Hierarchy→Add(左上角+)→XR→XR Origin(VR)

手柄设置

  1. 选中Hierarchy的XR Origin子物体LeftHand Controller

  2. 配置LeftHand Controller的控件XR Controller,点击在右上角的预设,选择XRI Default Left Controller (右手柄同样配置,选择XRI Default Right Controller )

  3. 选择手柄模型,在XR Controller的Model Prefab选择LeftControllerModel(Tranform)

打包设置

选择:Edit→Player→settings for Android→other Setting

Minimum API Level 选择Android 10.0

Target API Level 选择Automatic(Highest installed)

Scripting Backend 选择IL2CPP

勾选ARM64

选择:Edit→Project Settings→XR Plug-in Management→Android Standalone Settings→选择PICO

3、开发工具

SDK安装

下载地址:SDK - PICO 开发者平台 (PICO Unity Live Preview Plugin)

SDK下载后解压

打开unity→Window→PackgeManager→Add Package From disk(左上角+)→选择解压后文件里的package.json

windows下载客户端

下载地址:SDK - PICO 开发者平台 (PICO Developer Center)

在本地安装后会安装steam串流工具

为一体机开启开发者模式

  1. 开启 PICO VR 一体机。
  2. 前往 设置 > 通用
  3. 射线对准 设置 字段并连续点击多次,直到左侧导航栏下方出现 开发者 选项。
  4. 点击 开发者,进入开发者选项界面。
  5. 打开右上角的 USB 调试开关

*这里官方文档有误,开启开发者模型要多次点击设置键

项目设置

选择:Edit→Project Settings→XR Plug-in Management→ PC Standalone Settings→选择 PICO Live Preview

二、开发

1、手柄输入

得到手柄

    InputDevice deviceLeft;//左手柄
    InputDevice deviceRight;//右手柄
    private void Start()
    {
        deviceLeft = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
        deviceRight = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
    }

手柄触发核心方法 TryGetFeatureValue

手柄扳机键触发

    /// <summary>
    /// 扳机键
    /// </summary>
    /// <param name="inputDevice">手柄</param>
    /// <param name="action">触发委托</param>
    /// <param name="Value">触发参数</param>
    void triggerButton(InputDevice inputDevice, ref bool Value, Action action)
    {
        if (inputDevice.TryGetFeatureValue(CommonUsages.triggerButton,out Value)&&Value)
        {
            action();
        }
    }

扳机键力度

    /// <summary>
    /// 扳机键力度
    /// </summary>
    /// <param name="inputDevice">手柄</param>
    /// <param name="action">触发委托</param>
    /// <param name="Value">触发参数</param>
    void trigger(InputDevice inputDevice, ref float Value, Action<float> action)
    {
        if (inputDevice.TryGetFeatureValue(CommonUsages.trigger, out Value)&& !Value.Equals(0))
        {
            action(Value);
        }
    }

抓握键

    /// <summary>
    /// 抓握键
    /// </summary>
    /// <param name="inputDevice"></param>
    /// <param name="action"></param>
    /// <param name="Value"></param>
    void gripButton(InputDevice inputDevice, ref bool Value, Action action)
    {
        if (inputDevice.TryGetFeatureValue(CommonUsages.gripButton, out Value) && Value)
        {
            action();
        }
    }

抓握键力度

    /// <summary>
    /// 抓握键力度
    /// </summary>
    /// <param name="inputDevice"></param>
    /// <param name="action"></param>
    /// <param name="Value"></param>
    void grip(InputDevice inputDevice, ref float Value, Action<float> action)
    {
        if (inputDevice.TryGetFeatureValue(CommonUsages.grip, out Value) && !Value.Equals(0))
        {
            action(Value);
        }
    }

摇杆方向

    /// <summary>
    /// 摇杆方向
    /// </summary>
    /// <param name="inputDevice"></param>
    /// <param name="action"></param>
    /// <param name="Value"></param>
    void primary2DAxis(InputDevice inputDevice, ref Vector2 Value, Action<Vector2> action)
    {
        if (inputDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out Value) && !Value.Equals(Vector2.zero))
        {
            action(Value);
        }
    }

摇杆

    /// <summary>
    /// 摇杆
    /// </summary>
    /// <param name="inputDevice"></param>
    /// <param name="Value"></param>
    /// <param name="action"></param>
    void primary2DAxisClick(InputDevice inputDevice, ref bool Value, Action action)
    {
        if (inputDevice.TryGetFeatureValue(CommonUsages.primary2DAxisClick, out Value) && Value)
        {
            action();
        }
    }

X/A

    /// <summary>
    /// X/A
    /// </summary>
    /// <param name="inputDevice"></param>
    /// <param name="Value"></param>
    /// <param name="action"></param>
    void primaryButton(InputDevice inputDevice, ref bool Value, Action action)
    {
        if (inputDevice.TryGetFeatureValue(CommonUsages.primaryButton, out Value) && Value)
        {
            action();
        }
    }

Y/B

    /// <summary>
    /// Y/B
    /// </summary>
    /// <param name="inputDevice"></param>
    /// <param name="Value"></param>
    /// <param name="action"></param>
    void secondaryButton(InputDevice inputDevice, ref bool Value, Action action)
    {
        if (inputDevice.TryGetFeatureValue(CommonUsages.secondaryButton, out Value) && Value)
        {
            action();
        }
    }

2、射线

得到射线的方法

XRRayInteractor.TryGetCurrent3DRaycastHit(out hit)

XRRayInteractor是手柄上挂载的XRRayInteractor脚本。

Demo

    public XRRayInteractor rayInteractor;
    RaycastHit hit;
    Vector3 getRayPoint()
    {
        if (rayInteractor.TryGetCurrent3DRaycastHit(out hit))
        {
           
            string name = hit.collider.name;
            Debug.Log(name);
            return hit.point;
        }
        else
        {
            return Vector3.zero;
        }
    }

补充设置

射线的类型

类型说明
Staight Line直线
Projectile Curve抛物线
Bezier Curve贝塞尔曲线

修改方法

 rayInteractor.lineType = XRRayInteractor.LineType.ProjectileCurve;

不同类型的射线还有自己的参数可以修改,比如Stailght Line的MaxRaycastDistance(最远射线距离)和ProjectileCurve的Additional Flight Time(射线飞行时间)都可以直接赋值。

有效射线和无效射线

当射线触碰到可触发的UI或者模型时,射线为有效射线,反馈则是使用了ValidColorGradient。否则是使用InvalidColorGradient。

无效射线和有效射线触碰到有碰撞的模型时同样可以返回RaycastHit,区别在XR射线本身的设置上,比如碰撞Reticle。

实现有效碰撞,需要另外在模型上添加Tracked Device Physics Raycaster脚本等

Reticle (十字线)

Reticle 是射线和模型(UI)碰撞的点。

添加方法:

在手柄的上找到XR Interactor Line Visual脚本,创建Reticle 预制体后直接添加上。

3、UI触发

触发条件

手柄射线要触发到UI,在完成VR基础场景搭建的前提下,需要挂载两个脚本。

在Canvas上增加Tracked Device Graphic Raycaster

替换EventSystem上的Standalone Input Module为XR UI Input Module(模型上添加的Tracked Device Physics Raycaster脚本也是受XR UI Input Module影响的)

注意事项

Canvas的Order in Layer 最好设置为负值。如果为0或者正值,十字线可能会被UI遮挡。

为0时

为-1时

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/81436.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

12. Docker可视化工具

目录 1、前言 2、Docker UI 2.1、部署Docker UI 2.2、管理容器 3、Portainer 3.1、部署Portainer 3.2、管理容器 3.3、添加远程Docker 4、Shipyard 1、前言 Docker 提供了命令行工具来管理 Docker 的镜像和运行 Docker 的容器。我们也可以使用图形工具来管理 Docker。…

【k8s、云原生】基于metrics-server弹性伸缩

第四阶段 时 间&#xff1a;2023年8月18日 参加人&#xff1a;全班人员 内 容&#xff1a; 基于metrics-server弹性伸缩 目录 一、Kubernetes部署方式 &#xff08;一&#xff09;minikube &#xff08;二&#xff09;二进制包 &#xff08;三&#xff09;Kubeadm 二…

STM32——RTC实时时钟

文章目录 Unix时间戳UTC/GMT 时间戳转换BKP简介BKP基本结构读写BKP备份寄存器电路设计关键代码 RTC简介RTC框图RTC基本结构硬件电路RTC操作注意事项读写实时时钟电路设计关键代码 Unix时间戳 Unix 时间戳&#xff08;Unix Timestamp&#xff09;定义为从UTC/GMT的1970年1月1日…

周易卦爻解读笔记——节卦

第六十卦节 水泽节 坎上兑下 节卦由泰卦所变&#xff0c;泰卦的九三与六五换位。象征节制有度。 地天泰 节卦是涣卦的覆卦&#xff0c;序卦传【物不可以终离&#xff0c;故受之以节】 节&#xff1a;亨。苦节不可贞。 节卦通达&#xff0c;但不可一直过度辛苦的节制。 彖曰…

机器学习|Softmax 回归的数学理解及代码解析

机器学习&#xff5c;Softmax 回归的数学理解及代码解析 Softmax 回归是一种常用的多类别分类算法&#xff0c;适用于将输入向量映射到多个类别的概率分布。在本文中&#xff0c;我们将深入探讨 Softmax 回归的数学原理&#xff0c;并提供 Python 示例代码帮助读者更好地理解和…

JVM面试题-1

1、什么是JVM内存结构&#xff1f; jvm将虚拟机分为5大区域&#xff0c;程序计数器、虚拟机栈、本地方法栈、java堆、方法区&#xff1b; 程序计数器&#xff1a;线程私有的&#xff0c;是一块很小的内存空间&#xff0c;作为当前线程的行号指示器&#xff0c;用于记录当前虚拟…

【以太网通信】RS232 串口转以太网

最近和 RK 研发同事在调试通信接口&#xff0c;排查与定位 RK3399 接收数据出错的问题。FPGA 与 RK3399 之间使用一路 RS232 串口进行通信&#xff0c;由于串口数据没有分包&#xff0c;不方便排查问题&#xff0c;想到可以开发一个 RS232 串口转以太网的工具&#xff0c;将串口…

nginx部署时http接口正常,ws接口404

可以这么配置 map $http_upgrade $connection_upgrade {default upgrade; close; }upstream wsbackend{server ip1:port1;server ip2:port2;keepalive 1000; }server {listen 20038;location /{ proxy_http_version 1.1;proxy_pass http://wsbackend;proxy_redirect off;proxy…

谷歌浏览器插件篇之console Importer

前言 作为一名前端开发者&#xff0c;相信在开发实践中&#xff0c;使用过诸多第三方库。譬如&#xff1a;lodash、moment、dayjs、antd等数不胜数。 然每每使用&#xff0c;经起繁琐&#xff0c;便令人有反抗之意。其步骤如下&#xff1a;首先要在搭建好的项目里&#xff0c…

学习笔记:Opencv实现限制对比度得自适应直方图均衡CLAHE

2023.8.19 为了完成深度学习的进阶&#xff0c;得学习学习传统算法拓展知识面&#xff0c;记录自己的学习心得 CLAHE百科&#xff1a; 一种限制对比度自适应直方图均衡化方法&#xff0c;采用了限制直方图分布的方法和加速的插值方法 clahe&#xff08;限制对比度自适应直方图…

C++ string类详解

⭐️ string string 是表示字符串的字符串类&#xff0c;该类的接口与常规容器的接口基本一致&#xff0c;还有一些额外的操作 string 的常规操作&#xff0c;在使用 string 类时&#xff0c;需要使用 #include <string> 以及 using namespace std;。 ✨ 帮助文档&…

4 STM32标准库函数 之 FLASH存储器(FLASH)所有函数的介绍及使用

3 STM32标准库函数 之 FLASH存储器所有函数的介绍及使用 1. 图片有格式2 文字无格式二、FLASH 库函数固件库函数预览2.1 函数FLASH_SetLatency2.2 函数FLASH_HalfCycleAccessCmd2.3 函数FLASH_PrefetchBufferCmd2.4 函数FLASH_Unlock2.5 函数FLASH_Lock2.6 函数FLASH_ErasePage…

音视频 FFmpeg音视频处理流程

ffmpeg -i test_1920x1080.mp4 -acodec copy -vcodec libx264 -s 1280x720 test_1280x720.flv推荐一个零声学院项目课&#xff0c;个人觉得老师讲得不错&#xff0c;分享给大家&#xff1a; 零声白金学习卡&#xff08;含基础架构/高性能存储/golang云原生/音视频/Linux内核&am…

GAN!生成对抗网络GAN全维度介绍与实战

目录 一、引言1.1 生成对抗网络简介1.2 应用领域概览1.3 GAN的重要性 二、理论基础2.1 生成对抗网络的工作原理2.1.1 生成器生成过程 2.1.2 判别器判别过程 2.1.3 训练过程训练代码示例 2.1.4 平衡与收敛 2.2 数学背景2.2.1 损失函数生成器损失判别器损失 2.2.2 优化方法优化代…

Linux设置临时目录路径的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

第 7 章 排序算法(1)(介绍,分类,时间复杂度,空间复杂度)

7.1排序算法的介绍 排序也称排序算法(Sort Algorithm)&#xff0c;排序是将一组数据&#xff0c;依指定的顺序进行排列的过程。 7.2排序的分类&#xff1a; 内部排序: 指将需要处理的所有数据都加载到**内部存储器(内存)**中进行排序。外部排序法&#xff1a; 数据量过大&am…

安全学习DAY18_信息打点-APP资产搜集

信息打点-APP资产&静态提取&动态抓包&动态调试 文章目录 信息打点-APP资产&静态提取&动态抓包&动态调试本节知识&思维导图本节使用到的链接&工具 如何获取目标APP从名称中获取APP从URL获取APP APP搜集资产信息APP提取信息分类信息提取方式信息…

RPA机器人《国网电力》电力行业实施案例-基层减负 提质增效

背景&#xff1a;随着国网战略目标加速落地&#xff0c;数字化转型和精益化管理深化推进&#xff0c;各供电公司亟待突破精细化管控不深入、执行标准不够统一、系统数据不够融通等制约工作质效提升的能力瓶颈&#xff0c;针对这些问题&#xff0c;决定引入诸如RPA、OCR等技术&a…

深入探索:Kali Linux 网络安全之旅

目录 前言 访问官方网站 导航到下载页面 启动后界面操作 前言 "Kali" 可能指的是 Kali Linux&#xff0c;它是一种基于 Debian 的 Linux 发行版&#xff0c;专门用于渗透测试、网络安全评估、数字取证和相关的安全任务。Kali Linux 旨在提供一系列用于测试网络和…

C语言刷题指南(二)

&#x1f4d9;作者简介&#xff1a; 清水加冰&#xff0c;目前大二在读&#xff0c;正在学习C/C、Python、操作系统、数据库等。 &#x1f4d8;相关专栏&#xff1a;C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 &#x1f44d…