当前位置: 首页 > news >正文

从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动

从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动

文章目录

一、前言

在开发VR游戏的时候,第二个要解决的就是移动和转向问题,该专题将详细解析如何在VR世界中实现这些功能。

1、大纲

经过该教程你将学会

  1. 如何用扳机键或握把键(任君选)进行地区传送和锚点传送
  2. 如何通过左摇杆/右摇杆 转动画面
  3. 如何通过摇杆在场景中移动
  4. 初步熟悉 手柄按键与Unity中物体的交互方法

二、VR射线移动功能实现与解析

1、区域传送

(1)新建 XR Origin

XR – 》 Device-based --》 XR Origin(VR)
在这里插入图片描述
注:在层级窗口右键找不到XR选项的同学,可以参考之前的教程完成PICO开发环境配置:从零开始的PICO教程(1)Pico游戏开发项目配置

(2)新建一个用于传送的地面

  1. 在Hierarchy(层级窗口) 右键 3D Object --> Plane 新建地面
    • 但目前白色与传统的地面不是很像,我们给他修改颜色为灰色
  2. 在Project(项目窗口)右键 Create – 》Folder 创建一个文件夹,修改名字为:Materials,后续这个文件夹将专门用于存放Unity的材质
  3. 在Project(项目窗口)右键 Create – 》Material 创建一个材质,改名为gray在这里插入图片描述
  4. 点击材质调整颜色为灰色,然后将材质拖拽到Plane
  5. 为地面添加VR中常用的传送组件 Teleportation 在这里插入图片描述
  • Teleportation 组件介绍
    Teleportation是VR应用中流行的导航工具。用户可以指向并指示他们想要移动的目的地,并在发起传送命令时被传送到目的地。Teleportation是用户通过快速动画过渡到目标位置的运动,该动画经过调整以保持玩家舒适度。这是在 VR 中移动用户的最常见方式,同时将不适感降到最低。

    • Teleportation Area :添加组件后 该对象后将成为一个可传送对象,用途:地面、可站立位置
    • Teleportation Anchor:添加组件后 物体传送则只能传送到该物体的几何中心点上。一般Teleportation Anchor 都会结合Empty Object 使用,点击可传送对象,传送后将传送到指定位置,用途:传送阵、特殊地点
    • Teleportation Provider(传送提供者)
      Locomotion System中的一种特殊方式,用于快速将角色从一个位置瞬间传送到另一个位置。传送可以是在游戏场景中的固定点之间进行,也可以是根据玩家的输入或交互动作进行。传送通常用于解决长距离移动或跨越障碍物的问题,提供流畅的用户体验。
      Teleportation Provider可以与VR和AR设备的手柄、控制器或触摸界面等输入设备结合使用。通过触发传送操作,玩家可以在虚拟场景中快速移动到指定位置,而无需使用传统的行走或奔跑方式。这种传送方式在一些游戏、体验和虚拟导航应用中非常常见。

(3)将XR Origin设置为可传送的Provider 并赋值给可传送地面

  1. 将XR Origin设置为待传送的Provider对象
    在这里插入图片描述
  2. 让可传送地面知道,要传送誰在这里插入图片描述
  • Locomotion (运动系统)组件介绍
    用于控制角色或玩家在虚拟场景中移动的系统。它提供了一系列方法和工具,使角色可以在游戏场景中自由移动,并与环境进行交互。Locomotion System通常用于第一人称或第三人称的角色控制,以及虚拟现实(VR)和增强现实(AR)应用程序中的用户导航。
    它包含以下核心功能

  • 移动控制:Locomotion System提供了一种方式来控制角色的移动,比如使用键盘、鼠标、手柄或触摸屏等输入设备。它可以处理角色的前进、后退、旋转、跳跃等基本移动操作。

  • 碰撞检测:为了避免角色与场景中的物体产生穿越或碰撞,Locomotion System通常包含碰撞检测功能。它可以检测到障碍物、墙壁或其他物体,并阻止角色通过或与其发生碰撞。

  • 地形适应:在复杂的场景中,地形的高度变化或不规则形状可能会影响角色的移动。Locomotion System可以提供地形适应功能,使角色能够自动调整其移动方式,以适应地形的变化。

  • 动画控制:Locomotion System可以与角色的动画系统集成,以实现平滑的移动过渡和姿势控制。它可以根据角色的移动速度和方向来播放相应的动画。

本次教程主要使用到了其移动控制的功能,高阶教程中会再次使用到这些。现阶段了解即可。

(4)运行项目查看传送功能是否实现

利用PICO官方自带的PICO Unity Live Preview Plugin 实现 实时预览应用场景的功能,还不能实时预览应用场景功能的同学可以查看:从零开始的PICO教程(2)–实时预览应用场景
在这里插入图片描述
射线触发到可传送地面时候,转变为激活状态的,颜色变为白色。按下握把键,触发传送事件,完成传送。传送功能实现。
注:进入VR世界的时候看不到地面,可能是头显位置在地面下面,提高头显高度即可。

2、锚点传送

(1)创建锚点传送地面

参考:区域传送的第二节 新建一个用于传送的地面 完成以下操作

  1. 进入层级窗口 Create – > Plane 创建平面。
  2. 选择plane下右键 Create Empty对象,重命名为anchor (射线点击Plane 将传送到该Empty对象的位置)
  3. 进入Project 窗口,在Materials文件夹下新建一个材质,名字为blue,修改颜色为blue。然后赋值给第一步新建的plane对象。
  4. 选择第一步创建的plane对象,添加组件Teleportation Anchor,然后拖拽第二步创建的anchor 空对象,到Teleport Anchor Transform上
    在这里插入图片描述
    到这里,就完成锚点传送啦,运行VR游戏,点击plane,头显将自动移动过去。

(2)修改传送触发按键

目前,默认是按握把键传送,如果我想扳机键传送又要怎么改呢?
在这里插入图片描述

改好后就完成咯,之后想要移动,点击右控制器的扳机键即可。
修改完后,建议大家运行一遍体验效果。

三、视角旋转

来到这一步,相信在座的各位都会遇到头显转向不方便的问题吧。假如我祭出摇杆转向头显又该如何应对呢?

1、XR Origin添加Snap Turn Provider组件

  1. 选择XR Origin对象,添加Snap Turn Provider组件,然后点击新增控制器,拖拽LeftHand Controller到XR Origin对象的Teleport Anchor Transform上

在这里插入图片描述
好好好,到这里,我们就可以通过左摇杆控制头显视角转动了。 大家可以运行在头显中查看是否已经能正常转动。
注:在这里,可以通过修改Turn Amount 来修改每按一次摇杆头显转动角度。

四、人物移动

目前能传送不晕,又能转向。离你在VR世界运动,只剩下移动咯,人物移动头显也会自动移动,但很多时候场景有限,这就需要我们拥有可以通过摇杆控制头显视角移动的功能

1、创建PlayControl脚本

  1. 在Project(项目窗口)右键 Create – 》Folder 创建一个文件夹,修改名字为:Scripts,后续这个文件夹将专门用于存放C#脚本
  2. 在Scripts文件夹内右键 Create – 》C# Script 创建一个脚本,改名为PlayControl
    PlayControl脚本内容如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
using UnityEngine.XR.Interaction.Toolkit;public class PlayControl : MonoBehaviour
{// 传入右控制器的引用 public XRController rightController;//小球的移动速度public float Speech=2.0f;void Start(){}void Update(){//存储摇杆的在一个x,y轴上的移动数据 Vector2 result;//判断玩家是否移动了摇杆bool ret;//out 类似一个引用声明,primary2DAxis 修改的值可以通过out 后面的参数也就是result获得ret = rightController.inputDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out result);if (ret){Vector3 currentPosition = this.transform.position;this.transform.Translate(Speech * result.x * Time.deltaTime, 0, Speech * result.y * Time.deltaTime);}}
}

注意:脚本名字一定要跟里面的公共 类的类名一样是:PlayControl。如果不一样,则任意修改这两者中的一个,使其一样即可。

2、将PlayControl脚本赋值给XR Origin

在这里插入图片描述
这样就实现了,右摇杆控制人物移动的功能

五、手柄与脚本组件交互

如果我想为手柄的其他功能为其赋值,该怎么做呢?
在这里插入图片描述
我们可以用
函数:inputDevice.TryGetFeatureValue获取手柄上的按键
CommonUsages属性则可以选择该回调函数是获取手柄上哪个按键。

CommonUsages值对应手柄按键
CommonUsages.primary2DAxis摇杆
CommonUsages.grip握把键
CommonUsages.trigger扳机键

下面我将举个例子,实现按下握把键加速,松开速度降低的功能

将脚本PlayControl 修改如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
using UnityEngine.XR.Interaction.Toolkit;public class PlayControl : MonoBehaviour
{// 传入右控制器的引用 public XRController rightController;//小球的移动速度float Speech=2.0f;void Start(){}void Update(){//存储摇杆的在一个x,y轴上的移动数据 Vector2 result;float pressedThre;//判断玩家是否移动了摇杆bool ret;bool retGripPress = rightController.inputDevice.TryGetFeatureValue(CommonUsages.grip, out pressedThre);if (retGripPress){Speech = pressedThre * 6;}//out 类似一个引用声明,primary2DAxis 修改的值可以通过out 后面的参数也就是result获得ret = rightController.inputDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out result);if (ret){Vector3 currentPosition = this.transform.position;this.transform.Translate(Speech * result.x * Time.deltaTime, 0, Speech * result.y * Time.deltaTime);}}
}

本次代码主要功能:将握把键 的按压程度(0~1)传入pressedThre,然后再将其做为速度,这样就可以实现,按的越下速度越快的效果了。
其余的按键也可以通过这种方法来获得,后续如果要求的人比较多,会再出一版pico 手柄教程。
在这里插入图片描述

六、结束

通过这章VR世界 射线传送、旋转和移动VR世界 射线传送、旋转和移动,你已经可以制作一个简单的街景VR啦,下一章让我们来制作开始本次VR开发教程的第一个实战项目吧。



该教程由:深圳技术大学 – 元宇宙开发者协会 撰写提供。如果是本学校学生欢迎加入 元宇宙开发者协会 你会见识到一个与众不同的社团
元宇宙开发相关合作欢迎发送 协会邮箱:2981007652@qq.com

相关文章:

从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动

从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动 文章目录 从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动一、前言1、大纲 二、VR射线移动功能实现与解析1、区域传送(1)新建 XR Orig…...

防止攥改之水印功能组件

防止攥改之水印功能组件 效果图逻辑代码 效果图 逻辑代码 <template><div class"containerBox" ref"parentRef" style"height: 300px;background-color: red;"><slot></slot></div> </template><script…...

iOS 17 适配 Xcode 15 问题

在适配 iOS 17 xcode 15时遇到的问题&#xff0c;记录一下。 1、 Could not build module ‘WebKit’ type argument nw_proxy_config_t (aka struct nw_proxy_config *) is neither an Objective-C object nor a block type解决方案&#xff1a; 选中不能编译的库的xcodep…...

Element Plus 快速开始

1.完整引入&#xff08;全局引入&#xff09; // main.ts import { createApp } from vue import ElementPlus from element-plus import element-plus/dist/index.css import App from ./App.vueconst app createApp(App)app.use(ElementPlus) app.mount(#app) npm install e…...

华为云云耀云服务器L实例评测|StackEdit中文版在线Markdown笔记工具

华为云云耀云服务器L实例评测&#xff5c;StackEdit中文版在线Markdown笔记工具 一、云耀云服务器L实例介绍1.1 云服务器介绍1.2 应用场景1.3 支持镜像 二、云耀云服务器L实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 StackEdit 中文版3.1 StackEdit 介绍3.2 环…...

MyEclipse报错javax/persistence/EntityManagerFactory

MyEclipse报错&#xff1a; Build path is incomplete. Cannot find class file for javax/persistence/EntityManagerFactory 解决方案&#xff1a; 引入依赖 <dependency><groupId>javax.persistence</groupId> <artifactId>persistence-api</a…...

【MySQL进阶】SQL性能分析

一、SQL性能分析 1.SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以提供服务器状态信 息。通过如下指令&#xff0c;可以查看当前数据库的 INSERT 、 UPDATE 、 DELETE 、 SELECT 的访问频次&#xff1a; -- session 是查看当…...

在SpringBoot项目中整合SpringSession,基于Redis实现对Session的管理和事件监听

1、SpringSession简介 SpringSession是基于Spring框架的Session管理解决方案。它基于标准的Servlet容器API&#xff0c;提供了Session的分布式管理解决方案&#xff0c;支持把Session存储在多种场景下&#xff0c;比如内存、MongoDB、Redis等&#xff0c;并且能够快速集成到Spr…...

浅析vue中computed,method,watch,watchEffect的区别

方法methods只要调用每次都会执行watch(惰性)只有依赖项更新才会执行回调函数&#xff0c;且组件初次渲染不会执行watchEffect:自动追踪依赖变化&#xff0c;只要依赖更新即执行回调函数&#xff0c;且组件初次渲染即执行回调函数computed(惰性): 返回一个只读的ref,具有缓存功…...

activiti7的数据表和字段的解释

activiti7的数据表和字段的解释 activiti7版本有25张表&#xff0c;而activiti6有28张表&#xff0c;activiti5有27张表&#xff0c;绝大部分的表和字段的含义都是一样的&#xff0c;所以本次整理的activiti7数据表和字段的解释&#xff0c;也同样适用于activiti6和5。 1、总览…...

Java手写Trie树和Trie树应用拓展案例

Java手写Trie树和Trie树应用拓展案例 1. 算法思维导图 以下是使用mermaid代码表示的Trie树的实现原理&#xff1a; #mermaid-svg-5twy24X7Wqbhyulb {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-5twy24X7Wqbhyul…...

alova.js快速入门教程

官网地址&#xff1a;Alova.JS - Lightweight request strategy library | Alova.JS 目录 一、alova 是什么&#xff1f; 二、 快速入门 1、安装依赖 &#xff08;1&#xff09;使用npm方式安装 &#xff08;2&#xff09;使用yarn方式安装 2、在静态 html 中使用 一、al…...

获取IP地址-根据IP获取位置信息

获取外网IP地址&#xff0c;并得到该地址所在位置&#xff1b; 如&#xff1a;101.249.255.255 对应&#xff1a;西藏自治区-拉萨市-堆龙德庆区 string ipAddress GetIPAddress(); string location GetIPLocation(ipAddress); /// <summary>/// 获取IP地址/// </s…...

Android13适配-Google官方照片视频选择器

官方照片选择器 图 1. 照片选择器提供了一个直观的界面&#xff0c;便于与您的应用分享照片。 照片选择器的界面可供浏览和搜索&#xff0c;并按日期降序向用户显示其媒体库中的文件。如隐私保护最佳实践 Codelab 中所示&#xff0c;照片选择器为用户提供了一种安全的内置授权…...

云计算的发展趋势和挑战

本文将探讨云计算的发展趋势和挑战&#xff0c;旨在帮助读者了解云计算的最新动态和未来发展方向。 随着信息技术的发展&#xff0c;云计算作为一种新兴的计算模式&#xff0c;已经得到了广泛的应用和认可。它通过将计算资源、存储资源和应用程序等服务通过互联网提供给用户&a…...

PyG-GAT-Cora(在Cora数据集上应用GAT做节点分类)

文章目录 model.pymain.py参数设置运行图 model.py import torch.nn as nn from torch_geometric.nn import GATConv import torch.nn.functional as F class gat_cls(nn.Module):def __init__(self,in_dim,hid_dim,out_dim,dropout_size0.5):super(gat_cls,self).__init__()s…...

java专项练习(验证码)

package 专题练习;import java.util.Random;public class Developing_CAPTCHA {public static void main(String[] args) {/* 需求:定义方法生成一个5位的验证码 验证码长度为5,前四位为大或小写字母,最后一位是数字*///方法: 如果我们要在一堆没有规律的数据中随机抽取,可以先…...

MS1861 视频处理与显示控制器 HDMI转MIPI LVDS转MIPI带旋转功能 图像带缩放,旋转,锐化

1. 基本介绍 MS1861 单颗芯片集成了 HDMI 、 LVDS 和数字视频信号输入&#xff1b;输出端可以驱动 MIPI(DSI-2) 、 LVDS 、 Mini-LVDS 以及 TTL 类型 TFT-LCD 液晶显示。可支持对输入视频信号进行滤波&#xff0c;图 像增强&#xff0c;锐化&#xff0c;对比度调节&am…...

广州华锐互动:利用VR复原文化遗址,沉浸式体验历史文物古迹的魅力

在过去的几十年里&#xff0c;科技发展飞速&#xff0c;为我们打开了无数新的视角和可能性。其中&#xff0c;虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;技术的崭新应用&#xff0c;为我们提供了一种全新的、近乎身临其境的体验历史的方式。本文将重点…...

微信小程序——事件监听

微信小程序是一种轻量级的应用程序&#xff0c;它在移动设备上提供了丰富的用户体验。在开发微信小程序时&#xff0c;事件监听是一项重要的技术&#xff0c;它允许开发者捕捉和处理用户的各种操作。本文将介绍微信小程序事件监听的概念、用法和一些实用示例。 1. 什么是事件监…...

View绘制流程的源码所得

一些问题 子线程可以更新 UI 吗 答案是可以的&#xff0c;在特定的情况下可以 可以先在主线程中调用requestLayout() 方法&#xff0c;然后紧接着在子线程中更新UI&#xff08;原理&#xff1a;不要在子线程触发 checkThread() 方法&#xff0c;而checkThread() 方法的调用时…...

企业级数据仓库-理论知识

D3 AM 大数据中间件 Hive&#xff1a;将SQL转化成分布式Map/Reduce进行运算&#xff0c;也支持转换成Spark,需要单独安装Hive集群才能访问Spark,支持60%的SQL&#xff0c;延迟比较大。SparkSQL:属于Spark生态圈&#xff0c;Hive on Sqark。HBase: NoSQL,高并发读&#xff0c;适…...

解决flutter不识别yaml里面配置的git项目

解决办法找到相应的 git路径&#xff0c;然后手动 git pull 暂时先用这个笨方法&#xff0c;后面有更好的解决办法了再说 studio 自己拉取的项目里面没有ios 和lib包...

rust结构体

一、定义结构体类型 语法 struct Name_of_structure {field1: data_type,field2: data_type,field3: data_type, }注意&#xff1a; 不同于C&#xff0c;Rust的struct语句仅用来定义类型&#xff0c;不能定义实例。 结尾不需要;。 每个字段定义之后用 , 分隔。最后一个逗号可…...

Python - 小玩意 - 键盘记录器

pip install keyboardimport keyboard import timedef get_time():date_time time.strftime("%Y-%m-%d %H:%S", time.localtime())return date_timedef abc(x):if x.event_type down:print(f"{get_time()}你按下了{x.name}")with open(./键盘记录器.txt,…...

msvcp71.dll丢失的解决方法分享,全面分析msvcp71.dll丢失原因

msvcp71.dll 丢失的问题可能困扰着许多使用 Windows 操作系统的用户。msvcp71.dll 是微软 C运行时库中的一个动态链接库文件&#xff0c;负责提供一些基本的函数和类&#xff0c;例如字符串处理、数学运算、文件操作等。如果这个文件丢失或损坏了&#xff0c;那么在使用依赖于它…...

stm32----ADC模数转换

一、ADC介绍 ADC&#xff0c;即模数转换器&#xff0c;它可以将模拟信号转化为数字信号。在stm32种一般有3个ADC&#xff0c;每个ADC有18个通道。 12位ADC是一种逐次逼近型模拟数字转换器&#xff0c;它有多达18个通道&#xff0c;可测量16个外部和两个内部信号源。各个通道的A…...

Unity SteamVR 开发教程:用摇杆/触摸板控制人物持续移动(2.x 以上版本)

文章目录 &#x1f4d5;教程说明&#x1f4d5;场景搭建&#x1f4d5;创建移动的动作&#x1f4d5;移动脚本⭐移动⭐实时调整 CharacterController 的高度 &#x1f4d5;取消手部和 CharacterController 的碰撞 持续移动是 VR 开发中的一个常用功能。一般是用户推动手柄摇杆&…...

04条件构造器和常用接口

条件构造器和常用接口 wapper介绍 条件构造器的两个条件之间默认就是AND并列关系,如果需要或者的关系则需要调用构造器的or()方法 条件构造器类型作用Wrapper条件构造抽象类,最顶端父类AbstractWrapper生成SQL的where条件QueryWrapper封装查询或删除的条件UpdateWrapper封装修…...

什么是HTTP状态码?常见的HTTP状态码有哪些?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是HTTP状态码&#xff1f;⭐ 1xx - 信息性状态码⭐ 2xx - 成功状态码⭐ 3xx - 重定向状态码⭐ 4xx - 客户端错误状态码⭐ 5xx - 服务器错误状态码⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前…...