0


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

前言

公司之前用的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

最后

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

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

标签: vr unity 游戏引擎

本文转载自: https://blog.csdn.net/u010645062/article/details/126423571
版权归原作者 徐墨轩 所有, 如有侵权,请联系我们删除。

“ViveInputUtility入门教程_配置|瞬移|交互|UI|按钮事件|案例说明”的评论:

还没有评论