【Steam VR 2.0】5.射线操作UGUI-射线点击物体

2024-06-14 06:58

本文主要是介绍【Steam VR 2.0】5.射线操作UGUI-射线点击物体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

由于目前SteamVR的射线SteamVR_LaserPointer没有操作UGUI的功能,所以这里就不再对SteamVR_LaserPointer进行过多介绍,功能的实现借助插件【InputUtility】来实现,这个插件AssetStore可以免费获取。

插件的导入,有时会因为未编译SteamVR_Input而导致插件的按键无法使用,这里需要注意的是,导入steamVR选择openVR时,要选择较新的UnityVR,之后导入插件便会自动弹出Wizard窗口,AcceptAll即可。

1.操作UGUI

正确导入SteamVR2.0+和Input Utility后,可以在Input Utility的示例场景中,查看UGUI的操作案例

HTC.UnityPlugin - ViveInputUtility - Examples - 1.UGUI

将SteamVR里的Player与插件结合使用

结合Player的传送和插件的射线功能,Player传送功能的使用方法可以参考前面文章。

为Player添加操作射线的UI

1.将Player做成新预设,这里命名为PlayerUI,然后将新预设的Player UnpackPrefab

2.找到HTC.UnityPlugin - ViveInputUtility - Prefabs中的预设VivePointers,将其拖拽到PlayerUI中

SteamVRObject子物体下。保持位置和旋转为0

3.新建一个Canvas,选择word模式,摆放到面前,添加一个Button按钮,

为Canvas添加脚本CanvasRaycastTarget

运行,即可使用射线指向按钮,点击Trigger触发按钮,其他UGUI同理

兼容操作UI的射线与传送的射线

由于,player的传送与VivePointer的射线分属不同插件,我们需要在需要的时候,手动开启相关功能。否则会出现如下射线重叠的情况

传送指示的UI是在按住Pad时显示,松开时隐藏,那么我们只需要将操作UI的射线反向操作一下即可

这里我创建了一个脚本挂在预设PlayerUI的VivepPointer上,来方便获取

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class GetVivePointerUtility : MonoBehaviour
{public static GetVivePointerUtility instance;private void Awake() {instance = this;}
}

然后创建脚本PlayerUtility挂在PlayerUI上

 PlayerUtility.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Valve.VR;public class PlayerUtility : MonoBehaviour
{public SteamVR_Action_Boolean teleportAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("Teleport");private GameObject _vivePointer;//操作UI,射线物体private GameObject vivePointer {get {if (_vivePointer == null) {_vivePointer = GetVivePointerUtility.instance.gameObject;}return _vivePointer;}}private void Update() {if (teleportAction.GetStateDown(SteamVR_Input_Sources.Any)) {vivePointer.SetActive(false);}if (teleportAction.GetStateUp(SteamVR_Input_Sources.Any)) {vivePointer.SetActive(true);}}
}

至此即可完成一个带有传送及操作UGUI的基础环境

注:若需要将操作UI的射线,不一直显示,可以使用Menu键,点按,开启或关闭

2.借助VivePointer实现点击物体

VivePointer的射线可以在物体上监听射线Enter,Exit,Click等事件,还可以为Click绑定不同的按键,并且借助

eventData.pointerCurrentRaycast.worldPosition

可以获取到,射线点击到的点(世界坐标V3或者平面坐标V2)

1.直接获取手柄某按键点击(类似旧版SteamVR的按键获取方式)

用这种方式可以方便获取按键,并快捷绑定事件,缺点就是失去了部分SteamVR 2.0 input system的跨硬件优势,如果没有跨硬件需求,这种模式还是比较好用的。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HTC.UnityPlugin.Vive;public class TestA001 : MonoBehaviour
{private void Update() {if (ViveInput.GetPressDownEx(HandRole.RightHand, ControllerButton.Trigger)) {Debug.Log("Right Trigger");}if (ViveInput.GetPressDownEx(HandRole.LeftHand, ControllerButton.Trigger)) {Debug.Log("left Trigger");}}
}

2.射线与物体的交互

注意,命名空间的引用,这里使用了EventSystem的接口,所以场景中也需要有EventSystem(若使用了Player,则不需要手动添加EventSystem,因为player的InputModule上已经带有了EventSystem)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HTC.UnityPlugin.Vive;
using UnityEngine.EventSystems;public class TestB001 : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler {public void OnPointerClick(PointerEventData eventData) {if (eventData.IsViveButton(ControllerButton.Trigger)) {//获取按键点击,并且获取点击到的Raycast pointDebug.Log("Trigger Click point =" + eventData.pointerCurrentRaycast.worldPosition);}else if (eventData.button == PointerEventData.InputButton.Left) {Debug.Log("Standard button triggered");}}public void OnPointerEnter(PointerEventData eventData) {Debug.Log("Enter");}public void OnPointerExit(PointerEventData eventData) {Debug.Log("Exit");}
}

将脚本,挂载到一个cube上即可

这篇关于【Steam VR 2.0】5.射线操作UGUI-射线点击物体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1059691

相关文章

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

动手学深度学习【数据操作+数据预处理】

import osos.makedirs(os.path.join('.', 'data'), exist_ok=True)data_file = os.path.join('.', 'data', 'house_tiny.csv')with open(data_file, 'w') as f:f.write('NumRooms,Alley,Price\n') # 列名f.write('NA

线程的四种操作

所属专栏:Java学习        1. 线程的开启 start和run的区别: run:描述了线程要执行的任务,也可以称为线程的入口 start:调用系统函数,真正的在系统内核中创建线程(创建PCB,加入到链表中),此处的start会根据不同的系统,分别调用不同的api,创建好之后的线程,再单独去执行run(所以说,start的本质是调用系统api,系统的api

Java IO 操作——个人理解

之前一直Java的IO操作一知半解。今天看到一个便文章觉得很有道理( 原文章),记录一下。 首先,理解Java的IO操作到底操作的什么内容,过程又是怎么样子。          数据来源的操作: 来源有文件,网络数据。使用File类和Sockets等。这里操作的是数据本身,1,0结构。    File file = new File("path");   字

MySQL——表操作

目录 一、创建表 二、查看表 2.1 查看表中某成员的数据 2.2 查看整个表中的表成员 2.3 查看创建表时的句柄 三、修改表 alter 3.1 重命名 rename 3.2 新增一列 add 3.3 更改列属性 modify 3.4 更改列名称 change 3.5 删除某列 上一篇博客介绍了库的操作,接下来来看一下表的相关操作。 一、创建表 create

C# 防止按钮botton重复“点击”的方法

在使用C#的按钮控件的时候,经常我们想如果出现了多次点击的时候只让其在执行的时候只响应一次。这个时候很多人可能会想到使用Enable=false, 但是实际情况是还是会被多次触发,因为C#采用的是消息队列机制,这个时候我们只需要在Enable = true 之前加一句 Application.DoEvents();就能达到防止重复点击的问题。 private void btnGenerateSh

封装MySQL操作时Where条件语句的组织

在对数据库进行封装的过程中,条件语句应该是相对难以处理的,毕竟条件语句太过于多样性。 条件语句大致分为以下几种: 1、单一条件,比如:where id = 1; 2、多个条件,相互间关系统一。比如:where id > 10 and age > 20 and score < 60; 3、多个条件,相互间关系不统一。比如:where (id > 10 OR age > 20) AND sco

PHP7扩展开发之流操作

前言 啥是流操作?简单来讲就是对一些文件,网络的IO操作。PHP已经把这些IO操作,封装成流操作。这节,我们将使用PHP扩展实现一个目录遍历的功能。PHP示例代码如下: <?phpfunction list_dir($dir) {if (is_dir($dir) === false) {return;} $dh = opendir($dir);if ($dh == false) {ret

浙大数据结构:树的定义与操作

四种遍历 #include<iostream>#include<queue>using namespace std;typedef struct treenode *BinTree;typedef BinTree position;typedef int ElementType;struct treenode{ElementType data;BinTree left;BinTre

浙大数据结构:04-树7 二叉搜索树的操作集

这道题答案都在PPT上,所以先学会再写的话并不难。 1、BinTree Insert( BinTree BST, ElementType X ) 递归实现,小就进左子树,大就进右子树。 为空就新建结点插入。 BinTree Insert( BinTree BST, ElementType X ){if(!BST){BST=(BinTree)malloc(sizeof(struct TNo