ViveInputUtility入门教程_配置|瞬移|交互|UI|按钮事件|案例说明

目录

​​​​​​​

前言

下载

配置VR场景

瞬移

直线和抛物线

UI交互

交互(射线)

触碰

拾取

交互(手)

触碰

按压

点击

拾取

扔掉

综合案例

Input按钮

自定义设置按钮

像unity中Input那样获取手柄按键

常见问题

如何设置左手柄抛物线移动,右手柄发射直线

如何设置让直线不能参与瞬移

如何设置瞬移时,抛物线顶端的三角形提示变色

做一个提示面板跟着左手

如何判断一个物体被拾取了

可移动点和可移动区域

动态传送到指定地点

常用脚本说明

官方案例说明

0.Tutorial

1.UGUI

2.2DDragDrop

3.3DDrag

4.Teleport

5.ColliderEvent

6.ControllerManagerSample

7.RoleBindingExample

8.NearFieldHandInteraction

9.TrackedHandUGUIInteraction

10.ControllerTooltips

最后


前言

公司之前用的VRTK3.3,但是VRTK不支持SteamVR2.0.所以需要另外学习一个插件ViveInputUtility.

这是我的VRTK3教程,有兴趣可以看看.

​​​​​​​Unity虚拟现实插件VRTK3.3使用教程一:基本配置_徐墨轩的博客-CSDN博客_vrtk教程

unity store的链接:

VIVE Input Utility | Integration | Unity Asset Store

git链接:

https://github.com/ViveSoftware/ViveInputUtility-Unity

wiki里说了主要功能.

简单来说,vive只帮我们封装了VR必要的功能,方便了设备检测,传送,按键,UI交互等等,其他更复杂的功能就没有了.从功能上来说,没有VRTK提供的功能多,且没有VRTK3.3的文档详细.找来找去,只能找到git上wiki里的案例介绍.API似乎是没有专门做讲解.难怪VRTK3更让人喜欢.功能全,文档详细.

而且我找了一下CSDN,都是随便讲讲,唯一一个值得参考的就是这个链接了:

https://blog.csdn.net/obarong/article/details/52504638?ops_request_misc=&request_id=&biz_id=102&utm_term=ViveInputUtility&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-7-52504638.142^v40^pc_rank_34_queryrelevant0,185^v2^control&spm=1018.2226.3001.4187

而且原文的图片还丢了.

所以自己写了一个入门的教程.

下载

在unity商店里搜ViveInputUtility和SteamVR Plugin这两个插件.

ViveInputUtility其实就是对SteamVR 的封装.

 

下载安装后,点击vive的任意一个demo运行一下.结果又是要配置手柄,又是要选择用xr还是vr,根据提示自行判断就好.这里遇到一个问题,就是要求配置手柄按钮时,弹出的对话框点不掉.后来一直点点,就莫名其妙好了.demo也能正常运行了.

我用的unity版本号是2019.4.8

配置VR场景

不同设备不同平台需要做适配,还有vr中的基础互动操作这些工作都是由vive帮我们做过了.我们只需要使用他的预制体就ok了.

想看如果配置VR场景,直接运行vive第一个demo,场景里只有一个按钮.扣动手柄扳机键,可以触发按钮.

 

ViveCameraRig就像玩家本身,包括眼睛和手:查看VR场景必备

VivePointers就是手柄的射线:射线检测必备

ViveColliders:与3d物体交互必备(场景5)

ViveRig:综合了ViveCameraRig,VivePointers,ViveColliders功能,并且还提供了激活按钮选项.(在案例6中)

其他的:

ViveCurvePointers预制体抛物线,参考案例10;

HandPointers

TouchPointers

参考案例9,但是我没运行成功.

另外:说下CanvasRaycastTarget脚本

挂在Canvas,VR射线与UI交互必备

瞬移

很简单.在场景的地板上挂上Teleportable,脚本可以选择瞬移的按钮.需要注意的是,地板必须有碰撞体.对应官方demo4

直线和抛物线

用哪个拖哪个.

UI交互

这个没什么好说的,在配置Player上也说了,只要在Canvas上挂CanvasRaycastTarget脚本,就可以当正常的UI开发.

交互(射线)

触碰

拾取

被拾取的物体身上必须要有碰撞体,刚体可加可不加.另外物体还需要挂上Draggable脚本.默认情况下,可以通过摇杆来控制物体的远近.

但是这个Draggable却不是Vive的核心脚本,只是demo场景中的脚本.如果能看懂这个脚本,或许你会收获良多.

交互(手)

摸,按,点,拾,扔

交互条件:物体必须加碰撞体,刚体可加可不加.

//========= Copyright 2016-2022, HTC Corporation. All rights reserved. ===========

using UnityEngine.EventSystems;

namespace HTC.UnityPlugin.ColliderEvent
{
public interface IColliderEventHoverEnterHandler : IEventSystemHandler
{
void OnColliderEventHoverEnter(ColliderHoverEventData eventData);
}

public interface IColliderEventHoverExitHandler : IEventSystemHandler
{
void OnColliderEventHoverExit(ColliderHoverEventData eventData);
}

public interface IColliderEventLastHoverEnterHandler : IEventSystemHandler
{
void OnColliderEventLastHoverEnter(ColliderHoverEventData eventData);
}

public interface IColliderEventLastHoverExitHandler : IEventSystemHandler
{
void OnColliderEventLastHoverExit(ColliderHoverEventData eventData);
}

public interface IColliderEventPressDownHandler : IEventSystemHandler
{
void OnColliderEventPressDown(ColliderButtonEventData eventData);
}

public interface IColliderEventPressUpHandler : IEventSystemHandler
{
void OnColliderEventPressUp(ColliderButtonEventData eventData);
}

public interface IColliderEventPressEnterHandler : IEventSystemHandler
{
void OnColliderEventPressEnter(ColliderButtonEventData eventData);
}

public interface IColliderEventPressExitHandler : IEventSystemHandler
{
void OnColliderEventPressExit(ColliderButtonEventData eventData);
}

public interface IColliderEventClickHandler : IEventSystemHandler
{
void OnColliderEventClick(ColliderButtonEventData eventData);
}

public interface IColliderEventDragStartHandler : IEventSystemHandler
{
void OnColliderEventDragStart(ColliderButtonEventData eventData);
}

public interface IColliderEventDragFixedUpdateHandler : IEventSystemHandler
{
void OnColliderEventDragFixedUpdate(ColliderButtonEventData eventData);
}

public interface IColliderEventDragUpdateHandler : IEventSystemHandler
{
void OnColliderEventDragUpdate(ColliderButtonEventData eventData);
}

public interface IColliderEventDragEndHandler : IEventSystemHandler
{
void OnColliderEventDragEnd(ColliderButtonEventData eventData);
}

public interface IColliderEventDropHandler : IEventSystemHandler
{
void OnColliderEventDrop(ColliderButtonEventData eventData);
}

public interface IColliderEventAxisChangedHandler : IEventSystemHandler
{
void OnColliderEventAxisChanged(ColliderAxisEventData eventData);
}
}

触碰

在Vive里触摸不是touch,而是hover,如果一个物体想被触摸而触发事件,可以自定义脚本实现接口IColliderEventHoverEnterHandler

这里有OnColliderEventHoverEnter,OnColliderEventLastHoverEnter两种触摸进入接口.测试了一下,OnColliderEventHoverEnter进入触摸时只会触发一帧,但是OnColliderEventLastHoverEnter会触发好几帧.

碰了22次,OnColliderEventLastHoverEnter却触发了28次.不知道怎么算的.

按压

对着物体trigger键按下时,OnColliderEventPressEnter最先触发,接着OnColliderEventPressDown触发.

trigger键松开,OnColliderEventPressUp触发,最后OnColliderEventPressExit触发.

点击

对着物体点击trigger键,触发一帧

拾取

开始和结束都是一帧,update是每帧都触发.

需要注意的是,即使互动的3d物体没有加BasicGrabbable脚本,也会触发,但你会觉得怪怪的,正常开发拾取功能也不会这么做.

另外,在BasicGrabbable脚本上我并没找到物体是否被抓的判断,所以如果要判断该物体是否被抓住,或者被抓住时的逻辑处理.要么放在BasicGrabbable提供的After Grabbed事件函数上(1帧),要么只能自己新建脚本,继承对应接口来判断.

除了BasicGrabbable基础抓取的脚本外,vive还提供了另一种抓取脚本StickyGrabbable.(在场景5中体验)

StickyGrabbable效果是手松开,物体也不会放,再按一次按钮才会放.

StickyGrabbable多了个ToggleToRelease属性,就是来控制这个效果的.

扔掉

扔掉(松开手柄按键)的瞬间触发一帧.

综合案例

结合上面所讲,我们来写个demo:场景中一个按钮,一个桌子,按下按钮,桌子上会出现一把枪.拿起手枪,可以通过trigger键来发射子弹.

 搭建的场景是这样的.

脚本是这样的.

using HTC.UnityPlugin.ColliderEvent;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HTC.UnityPlugin.Vive;

public class MyGun : MonoBehaviour
{
    public Transform kou;//枪口的节点
    public bool isGrab;

    public float timerLimit = 0.5f;
    public float bulletPower = 1000f;
    private float t;
    // Start is called before the first frame update
    void Start()
    {
        float t = timerLimit;
    }

    // Update is called once per frame
    void Update()
    {
        
        t -= Time.deltaTime;
        if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.Trigger) && t <= 0 && isGrab)
        {
            GameObject bullet = Instantiate(Resources.Load<GameObject>("Bullet"));
            bullet.transform.SetParent(kou);
            bullet.transform.localPosition = Vector3.zero;
            bullet.transform.localRotation = Quaternion.identity;
            bullet.transform.parent = null;
            bullet.GetComponent<Rigidbody>().AddForce(kou.forward * bulletPower);
            t = timerLimit;
        }
    }
    public void IsGrab()
    {
        isGrab = true;
    }
    public void IsDrop()
    {
        isGrab = false;
    }

}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HTC.UnityPlugin.ColliderEvent;

public class MyPressBtn : MonoBehaviour, IColliderEventPressDownHandler, IColliderEventPressUpHandler
{
    public GameObject gun;

    public void OnColliderEventPressDown(ColliderButtonEventData eventData)
    {
        transform.position = new Vector3(1.52f, 0.58f, -2.47f);//下降位置
        gun.SetActive(true);
    }

    public void OnColliderEventPressUp(ColliderButtonEventData eventData)
    {
        transform.position = new Vector3(1.52f, 0.665f, -2.47f);//初始位置
    }
}

Input按钮

自定义设置按钮

获取手柄上按钮按键

 

 使用

 这个方法需要继承接口:IColliderEventPressEnterHandler

所有的HTC碰撞接口在HTC.UnityPlugin.ColliderEvent里.(在上文中交互(手)中有写)

像unity中Input那样获取手柄按键

if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.Trigger))

这样获取可以了.第一个参数是左右手判断,第二个参数是按键判断.

但这和unity的input一样,如果不加判断,是全局的,在vr中我们会经常按键,所以我们总要去加个判断.

常见问题

如何设置左手柄抛物线移动,右手柄发射直线

  1. 添加VivePointers和ViveCurvePointers
  2. 将ViveCurvePointers上的 ViveInputVirtualButton脚本取消勾选(注意是取消右手柄的脚本)
  3. VivePointers的Left子物体失活

如何设置让直线不能参与瞬移

没找到相关设置.

如何设置瞬移时,抛物线顶端的三角形提示变色

默认情况下,拖入Teleportable脚本到地板上不会自动设置,需要我们自己设置.

做一个提示面板跟着左手

参考案例10

如何判断一个物体被拾取了

上面综合案例有.

可移动点和可移动区域

vive插件的案例中并没有这样的例子.但是steamvr里是有的.估计vive觉的太简单了,开发者可以直接用steamvr得了

动态传送到指定地点

直接改变player位置

常用脚本说明

放几个链接弥补一下:

https://blog.csdn.net/obarong/article/details/52504638?ops_request_misc=&request_id=&biz_id=102&utm_term=ViveInputUtility&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-7-52504638.142^v40^pc_rank_34_queryrelevant0,185^v2^control&spm=1018.2226.3001.4187

【Unity+Vive】第二篇:Vive Input Utility API详解_奥巴荣的博客-CSDN博客

(有时间再填坑吧,vive为啥没有官方API说明)

ViveRoleSetter脚本:角色设置,用来设置该物体是什么角色.如手柄

VivePoseTracker:用于跟踪玩家实时位置

官方案例说明

https://github.com/ViveSoftware/ViveInputUtility-Unity/wiki/Example-0.Tutorial

0.Tutorial

概述:就是一个空场景,只有一个Button,可以通过射线点击.

ViveCameraRig就像玩家的头

VivePointers就是手柄的射线

而Canvas上挂了一个脚本:CanvasRaycastTarget.这个脚本的用途就是,挂在Canvas上,Canvas就变成了VR可交互的UI.

1.UGUI

和场景0差不多,多了一些ui控件

2.2DDragDrop

概述:拖动色块image,到指定面板或者3d物体上,可以改变其颜色.

可以看到拖拽的图片上挂了DragImage脚本

被拖拽到的面板图片上挂了DropImage脚本

被拖拽的3d物体上挂了DropObject脚本

3.3DDrag

概述:和2DDragDrop场景类似.只不过这是拖3d物体.另外,他还可以在拖拽的时候,通过手柄方向键来控制物体远近.一只手拽住的同时,另一只手抓住旋转也是可以的.

 3d物体上挂上Draggable脚本.3d物体上要有刚体和碰撞体

4.Teleport

概述:玩家通过按手柄摇杆键在场景中瞬移.

在场景的地板上挂上Teleportable,脚本可以选择瞬移的按钮.需要注意的是,地板必须有碰撞体.

另外比之前场景多了一个CustomDeviceHeight脚本.该脚本用来模拟玩家的高度.如果场景有物体比身高高,得蹲下来才能通过.

5.ColliderEvent

概述:这个场景主要是和场景中的3d物体交互.如触摸物体,拾取物体,按3d按钮,打开开关

可以被拾取的物体需要碰撞体,并且需要挂上脚本BasicGrabbable.这里物体添加刚体是为了模拟重力

 注意:这里除了交互物体需要设置外,在玩家身上需要增加一个预制体ViveColliders.不然没效果

另外就是Sticky效果是手松开,物体也不会放,再按一次按钮才会放;而base的抓取就是手松开就会掉.

而Unblockable和Blockable,试了半天,没看出来区别.

6.ControllerManagerSample

概述:这个场景怎么玩,已经写在panel里了,按菜单按钮会显示激光射线,按trigger键可以抓住3d物体,按grip键可以显示自定义的手柄.其他和场景5类似.

一开始这个地方的VROrigin我没看懂.里面既没有VivePointers,也没ViveColliders.运行后却有射线,也能与3d物体交互.难道ViveControllers代替了这两个预制体?实验了一下,确实是的.而且从预制体中脚本配置也能看出来.

7.RoleBindingExample

没太看懂,大概是绑定设备追踪的.

8.NearFieldHandInteraction

概述:3d面板会跟踪玩家视野.并且3d面板上的按钮可以互动.

看脚本里是可以操作按钮的,但是不知道为啥,我手柄和按钮无法交互.不知道是不是需要案例7去做配置.

9.TrackedHandUGUIInteraction

概述,:类似场景8,这里我也点击不了.

这个和TouchPointers预制体有关,应该是通过手直接触摸UI的功能吧.

10.ControllerTooltips

概述:右手柄按菜单键(我这里是B键),可以呼出一个跟随的面板,此时,手柄变成了面板上的鼠标,可以选择不同的颜色按钮.确定后,场景中的"回"字会变颜色.

如果有项目需要呼出小面板,在小面板上选择按钮事件,可以参考这个demo

最后

如果有帮到你请一键三连:)

如果文中有错误的地方请指出,谢谢.

  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值