vr全景接口

You would think that building a relatively simple VR Interface in Unity would be “Out of the Box” sort of work.

您可能会认为,在Unity中构建相对简单的VR接口将是“开箱即用”的工作。

Sadly, with a confused and confusing architecture, you are going to have to do much more work than you expected.

可悲的是,对于一个混乱而混乱的体系结构,您将不得不做比预期更多的工作。

背景 (Background)

Although I have no games development background, I recently started on a project to develop a business-oriented and data-oriented Virtual Reality application in Unity. More details about the project should be coming soon.

尽管我没有游戏开发背景,但是我最近开始了一个项目,该项目在Unity中开发面向业务和面向数据的虚拟现实应用程序。 有关该项目的更多详细信息应尽快推出。

As an experienced architect and developer coming new into the VR and Unity world, I want to cast some light onto the way to create a solution and hopefully help someone avoid the traps I have explored.

作为一个经验丰富的架构师和开发人员,我刚进入VR和Unity世界时,我想为创建解决方案提供一些启发,并希望帮助某人避免我探索的陷阱。

One note. I have noticed that many articles about Unity tend to start with the obvious about how to install it and then, at the critical point just say something equivalent to “then reverse polarity in the transduction mode of the matter curve”- without any explanation of what this means or, indeed, what to do with the matter curve if you don’t want the polarity reversed! I intend to assume the obvious and discourse more on the transduction mode. I hope I am successful.

一注。 我已经注意到,许多关于Unity的文章倾向于从关于如何安装Unity的显而易见的内容开始,然后在关键时刻只说了相当于“然后在物质曲线的转换模式下反转极性”的内容-对此没有任何解释。这意味着,或者实际上,如果您不希望极性反转,该如何处理物质曲线! 我打算在转导模式上承担更多显而易见的话题。 我希望我能成功。

There may be better solutions than we came up with. I am claiming to be far from an expert and I would love to hear about them: but the architecture is convoluted and the documentation is pretty much “ineffable”, so this path is the best that I could find.

可能有比我们想出的更好的解决方案。 我声称自己与专家相去甚远,我很想听听他们的意见:但是架构令人费解,文档几乎“无法解释”,所以这条路是我能找到的最好方法。

At the end, I give my views on what I wish this experience had been like and how the architecture should be managed.

最后,我对我希望这种经历是什么样的以及应该如何管理体系结构发表自己的看法。

目标 (Objectives)

First, lets lay down some objectives. We want to be able to explore in VR a data space and, in that space, to use Menus and interact with data entities using a typical ‘laser-pointer’ tool. That is all.

首先,让我们设定一些目标。 我们希望能够在VR中探索数据空间,并在该空间中使用菜单并使用典型的“激光指示器”工具与数据实体进行交互。 就这些。

We also want this to have a professional feel, so we don’t need any attempts at avatars or even hands (controller avatars are good enough) and we want good functionality in the menus, which should look like menus.

我们也希望它具有专业的感觉,因此我们不需要尝试任何化身甚至动手(控制器化身就足够了),并且我们希望菜单中的功能良好,应该看起来像菜单。

We also want this to be maintainable and so want to avoid technical debt and of course, we want to try to avoid reinventing everything to reduce the support load.

我们也希望这是可维护的,因此希望避免技术负担,当然,我们希望避免重新发明一切以减少支持负荷。

Let’s also for the time being that we want to work on Oculus only. But not close any doors to the future.

暂时让我们只想在Oculus上工作。 但没有关闭任何未来的大门。

起步 (Starting Out)

At first, everything seemed good.

起初,一切似乎都很好。

Core Unity provides a GameObject structure that can quite easily represent a spatial entity model (I hope to talk more about this in another article) along with the ability to create an application core using C# and C++.

Core Unity提供了一个GameObject结构,可以很容易地表示一个空间实体模型(我希望在另一篇文章中有更多介绍),以及使用C#和C ++创建应用程序核心的能力。

Looking at the Interface and Interaction model, you would think:

查看接口和交互模型,您会认为:

  • Unity has rolled out new Scriptable Render Pipeline technology (URP and HDRP for normal quality and High Def respectively) and has hinted that the legacy pipelines will eventually be sunsetted. It is a no brainer to use the URP to avoid technical debt.Unity推出了新的可脚本化渲染管道技术(分别为正常质量和高清的URP和HDRP),并暗示传统管道最终将被淘汰。 使用URP来避免技术债务是毫无道理的。
  • Unity has rolled out a new unified Input System and has stated that the old Input Managers will be deprecated. So in that goes.Unity推出了新的统一输入系统,并声明将淘汰旧的输入管理器。 所以就这样。
  • Oculus has a good integration package for Unity including all of the required Prefabs. Oculus has more incentive than anyone else to keep the integration supported and up to date and they should have more access to and knowledge of the low-level configurations. It seems to make sense to use this, particularly for the “XR-Rig” that is the representation of the user in VR space (i.e. the eyes and hands in their relative positions).Oculus为Unity提供了一个很好的集成包,其中包括所有必需的Prefabs。 Oculus比其他任何人都有更多的动力来保持对集成的支持并保持最新,并且他们应该更多地访问和了解底层配置。 使用它似乎很有意义,尤其是对于“ XR-Rig”,它是用户在VR空间中的表示(即,眼睛和手在其相对位置)。
  • For the Interactions, Unity has an XR Interaction Toolkit that is supposed to provide everything you need to interact with entities in VR, include a laser pointer. This has also just been released, so less technical debt.对于交互,Unity具有XR交互工具包,该工具包应提供与VR中的实体进行交互所需的一切,包括激光指示器。 这也刚刚发布,因此技术债务更少。
  • Finally, Unity has a new UI providing a good set of UI entities for creating Menus both in screen space and in world space.最后,Unity有一个新的UI,提供了一组不错的UI实体,可用于在屏幕空间和世界空间中创建菜单。

All good, yes?

都很好,是吗?

啊,但是……! (Ah, but …!)

It turns out that, basically, you cannot!

事实证明,基本上,您不能!

The first part was to migrate to URP (no problems) and convert the project from the deprecated “Built-in XR” to the XR Plugin system. It is a little surprising that the former, although deprecated, seems to be still the default. Configuring the Oculus plugin involved some fiddling with versions but they will presumably have fixed the version problems in the next releases.

第一部分是迁移到URP(没有问题)并将项目从不建议使用的“内置XR”转换为XR插件系统。 令人惊讶的是,尽管已弃用了前者,但它似乎仍然是默认值。 配置Oculus插件会涉及一些版本问题,但是大概会在以后的版本中修复版本问题。

But :

但是:

  • The Oculus Utilities for Unity do indeed provide all that is needed to build a good OVR (i.e. Oculus VR ) Rig and plugins for Unity. The documentation is also quite good. However, OUU is not URP ready and only provides integration to the legacy Input Manager and not to the new Input System,

    实际上, 用于Unity的Oculus实用程序确实提供了为Unity构建良好的OVR(即Oculus VR)装备和插件所需的全部功能。 该文档也相当不错。 但是,OUU还没有URP就绪,只能提供与旧版Input Manager的集成,而不能与新的Input System集成,

  • The Input System itself, although it does claim to support VR devices, only provides the most basic support. We could only actually get support through Legacy VR support emulating the mouse!

    输入系统本身虽然声称支持VR设备,但仅提供最基本的支持。 实际上,我们只能通过模拟鼠标的Legacy VR支持获得支持!

  • the XR Interaction Toolkit only works with its own XR Rig and on its own XR controller prefabs, which are no way as functional as the OUU Rig. There seems to be no easy way to wrap the OUU devices with entities from the XRIT. It does provide Interactors, like the laser pointer that we require, but it seems from the discussions that the focus is on grabbing items, which makes sense for games but is not what we want in this environment. It also true that the XRIT is not URP ready and the pointer is based on the Line Renderer, which means that the Ray has no 3D “body” and I personally find this and the rendering of the line when it should be occluded disconcerting. The pointer also Lerps VERYYYY slowly — for no apparent reason! It is pretty much useless.

    XR Interaction Toolkit仅可与自己的XR Rig和其自己的XR Controller预制件一起使用,而其功能不如OUU Rig。 用XRIT的实体包装OUU设备似乎没有简单的方法。 它确实提供了交互器,就像我们需要的激光指示器一样,​​但是从讨论中看来,重点放在抓取物品上,这对于游戏来说是有意义的,但在这种环境下并不是我们想要的。 确实,XRIT还没有URP就绪,并且指针是基于Line Renderer的,这意味着Ray没有3D“ body”,我个人认为应该这样做,并且应该遮挡线条时才渲染线条。 指针也慢慢变慢VERYYYY-没有明显的原因! 这几乎没有用。

  • The UI System does provide the tools required and DOES integrate with the Input System (as well as the Input Manager) and with the XRIT. However, since neither of those is integrated with OUU, that is of limited use. The documentation, not unreasonably, focuses on how to build UIs and not on integrating into VR and although you get the feeling that building one’s own integration is possible using the scripting API there are no hints about where to start.

    UI系统确实提供了所需的工具,并且DOES与输入系统(以及输入管理器)和XRIT集成在一起。 但是,由于这两个均未与OUU集成,因此用途有限。 该文档并非毫无道理地集中在如何构建UI上,而不是在与VR集成方面,尽管您感觉使用脚本API可以构建自己的集成,但没有关于从何开始的任何提示。

In general, I have to say that particularly the Unity components are architected from inside their box! It is a real shame that there is no guidance at all about how to add your own InputModule to the UI system or your own Interactors to the XRIT!

总的来说,我不得不说,特别是Unity组件是在其内部构造的! 真可惜,没有关于如何将自己的InputModule添加到UI系统或如何将自己的Interactor添加到XRIT的指导!

At this point, we also started to look for other frameworks to create VR Interfaces. The VR Toolkit (VRTK) seemed a good place to look, especially since it is open source. There are other frameworks available for purchase but we are wary of code lockin with closed source. However, VRTK has a big legacy problem, well described in this article, so we really want to start with V4.

在这一点上,我们也开始寻找其他框架来创建VR接口。 VR Toolkit(VRTK)看起来是一个不错的地方,特别是因为它是开源的。 还有其他框架可供购买,但是我们对带有封闭源的代码锁定保持谨慎。 但是,VRTK有一个大的遗留问题,已在本文中进行了详细描述,因此我们真的想从V4开始。

This version is very Beta! But they have a very nice pointer interactor and a very well developed Input Mapping and Event system for VR controllers.

这个版本是非常Beta版! 但是他们有一个非常好的指针交互器和一个非常发达的VR控制器输入映射和事件系统。

But, it does come out of the box with documented support for OUU.

但是,它确实具有对OUU的书面支持 。

However, it provides no interaction with the UI system! Or, less surprisingly, with the XRIT!

但是,它不提供与UI系统的交互! 或者,毫不奇怪,使用XRIT!

My architect's heart is saying that VRTK should be writing their Interactors to be compatible with XRIT (and Unity should be sponsoring them to do so). That way they would get UI Integration for free as well.

我的架构师的内心在说,VRTK应该编写其Interactor以使其与XRIT兼容(而Unity应该赞助他们这样做)。 这样,他们也将免费获得UI集成。

平方圆 (Squaring the Circle)

So. How did we solve this particular puzzle and meet our objectives?

所以。 我们如何解决这个特殊难题并实现我们的目标?

1 We started with the OVR XR Rig and Plugin from OUU, as the most functional. This gives you working head and controller tracking and controller avatars. You have to do the work to go through and change the shaders and material used in the prefabs to URP. We found that the URP Simple Lit shader works well with the default material.

1我们从OUU的OVR XR钻机和插件开始,这是功能最强大的。 这为您提供了工作头和控制器跟踪以及控制器的化身。 您必须完成以下工作才能将预制件中使用的着色器和材质更改为URP。 我们发现,URP Simple Lit着色器可与默认材质很好地配合使用。

2 We then added the VRTK Input Mapping by adding the UnityXR.Oculus.Left{Right}Controller GameObjects as described in this tutorial. These take the Input Bindings added to the Input Manager by the OVR Plugin and expose them as UnityEvents in a well-laid out and type-driven way. Not essential but incredibly useful. We, in the end, did NOT use the VRTK Tracked/Alias Rig — it actually gives you nothing that the OVR Rig does not do better and just adds runtime cost.

2然后,按照本教程中的说明,通过添加UnityXR.Oculus.Left {Right} Controller游戏对象来添加VRTK输入映射。 它们采用了由OVR插件添加到输入管理器的输入绑定,并以一种布局合理且类型驱动的方式将它们作为UnityEvents公开。 不是必需的,但是非常有用。 最后,我们没有使用VRTK跟踪/别名钻机-实际上,它没有给您带来OVR钻机做得更好的好处,而只是增加了运行时间成本。

The only problem with the Input Mapping is that, for some reason, the Controller GOs are not complete, they are missing all of the Axis controls and the grip control. It is a bit of work but not complicated to add those ( You can download the prefabs we created, provided with no warranty of any kind, for information only).

输入映射的唯一问题是,由于某种原因,控制器GO尚未完成,它们缺少所有的Axis控件和夹点控件。 添加这些工作有点繁琐,但并不复杂(您可以下载我们创建的预制件 ,不提供任何形式的保证,仅供参考)。

3 Both VRTK and XRIT provide Locomotion systems — mostly Teleport and Jump Turn. We are building a room-scale VR interface, so jump turns are counterproductive and whilst teleportation might have its uses in gameplay, it is pointless for exploring data. We built a simple set of utilities to move the model we are looking at and move the game around the model (using the left and right joysticks respectively) and it was very quick to integrate those scripts into the events from VRTK (10 minutes). We did the same thing with the Input System for non-VR use and it works pretty much the same way. The only pain was the need to create two complete sets of event Callbacks since the types are different! (for what it is worth, with no warranty and for information only, you can see our script here)

3 VRTK和XRIT都提供运动系统-主要是Teleport和Jump Turn。 我们正在构建一个房间级的VR接口,因此跳跃转弯会适得其反,虽然远距传送可能会在游戏玩法中使用,但探索数据毫无意义。 我们构建了一组简单的实用程序来移动我们正在查看的模型并在模型周围移动游戏(分别使用左右操纵杆),并且很快将这些脚本集成到VRTK的事件中(10分钟)。 对于非VR使用,我们对输入系统做了同样的事情,它的工作方式几乎相同。 唯一的麻烦是,由于类型不同,需要创建两个完整的事件回调集! (有关它的价值,不提供任何担保,并且仅作参考,您可以在此处查看我们的脚本)

4 VRTK has a very nice laser pointer Interactor. It is mesh-based so it has a real 3d feeling and it comes just as the beam, so you can easily add it to the OVR controller and it looks ok. It works out of the box and like VRTK Input Mapping, provides simple to use UnityEvents for when a collider enters the Raycast and when it leaves — which makes it easy to create your own callbacks for sending messages to entities based on the buttons. So that is what we did. The Interactors (from all frameworks) all come with their own state model of activated, selected, grabbed, touched etc which I suppose is great for a simple game but is useless if you just want to send a message to the entity to do something and usually want to send more than one type of “touched” message. We ended up writing all of that ourselves.

4 VRTK的激光指示器Interacto r 非常好 。 它基于网格,因此具有真实的3d感觉,并且就像光束一样出现,因此您可以轻松地将其添加到OVR控制器中,看起来还不错。 它像VRTK Input Mapping一样开箱即用,当碰撞器进入Raycast或离开Raycast时,它提供了易于使用的UnityEvents-这使创建基于按钮的消息发送到实体的回调变得容易。 这就是我们所做的。 交互器(来自所有框架)都具有其自己的激活,选定,抓取,触摸等状态模型,我认为这对于简单的游戏来说非常有用,但是如果您只想向实体发送消息以执行某项操作,则无用通常希望发送一种以上的“感动”消息。 我们最终自己写了所有这些。

satellite imagery © Mapbox
卫星影像©Mapbox

So we have a stereoscopic XR Rig integrated into the Oculus devices, with controller avatars and a laser pointer all working, the ability to move around and the ability to point at and manipulate entities using a laser pointer. Mostly out of the box with some business logic written in C# and integrated using UnityEvent callbacks.

因此,我们将一个立体XR钻机集成到Oculus设备中,其中控制器化身和激光指示器都可以工作,可以移动,并可以使用激光指示器指向和操纵实体。 多数情况下,开箱即用了一些用C#编写并使用UnityEvent回调进行集成的业务逻辑。

绝望菜单 (Menu of Despair)

Finally, we come to the menu part of the UI. And this is where the technical gap starts appearing between the systems.

最后,我们进入UI的菜单部分。 这就是系统之间出现技术差距的地方。

The Unity UI system does provide everything we need and it was relatively simple to create a world space canvas and add that, suitably scaled, to the left-hand anchor so that it appeared to be part of the left-hand controller.

Unity UI系统确实提供了我们需要的一切,创建一个世界空间画布并将其适当缩放后添加到左侧锚点相对简单,因此它似乎是左侧控制器的一部分。

Using the UnityEvents from the VRTK Input Mapping, it was also a few minutes work to make it so the menu only appeared when pressing controller button 3.

使用VRTK输入映射中的UnityEvents,还需要花费几分钟的时间,因此只有在按下控制器按钮3时菜单才会出现。

But, you need to be able to press the menu buttons!

但是,您需要能够按菜单按钮!

After trying many things — we actually settled back on XRIT as being the only good way of integrating into the UI. But with a twist.

在尝试了许多事情之后,我们实际上将XRIT定位为集成到UI的唯一好方法。 但是有一个转折。

Setting up the XRIT for use with the UI is well documented. You must have an XR Interaction Manager and a UI EventSystem in your scene, and the EventSystem must use the XRUI InputModule. Also — your UI canvas must have an additional raycaster. However, nothing complicated.

设置XRIT以与UI一起使用已被详细记录 。 您的场景中必须具有XR Interaction Manager和UI EventSystem,并且EventSystem必须使用XRUI InputModule。 另外,您的UI画布必须具有附加的raycaster。 但是,没有什么复杂的。

You also need an interactor. We discussed above the reasons for not using the XRIT pointer and the VRTK pointer is not an XRIT interactor. We could have used an XRIT direct interactor attached to the right controller to touch the buttons, but we could never make that work (we think it is some sort of interaction between the XR Controller that XRIT insists to add to an Interactor and the OVR Controller) and anyway — we wanted to use the pointer.

您还需要一个交互器。 上面我们讨论了不使用XRIT指针且VRTK指针不是XRIT交互器的原因。 我们可以使用连接到正确控制器的XRIT直接交互器来触摸按钮,但是我们永远无法完成这项工作(我们认为XRIT坚持要添加到Interactor的XR控制器和OVR控制器之间是某种交互方式),无论如何-我们想使用指针。

So our solution was to make the VRTK pointer into an XRIT Interactor. This is certainly in the spirit of the documentation (although it does not say how to do it) and is allowed by the license. And, it is done through published APIs so should have some future. However, this is the weak point of this design.

因此,我们的解决方案是使VRTK指针成为XRIT Interactor。 这当然是本文档的精神(尽管它没有说明如何做),并且已获得许可。 而且,它是通过已发布的API完成的,因此应该有一定的发展前景。 但是,这是该设计的弱点。

EDIT — the previous version of this post used a box collider to cause the pointer to terminate on the UI Element. This proved to both be unnecessary and to cause problems if the menu is moving in world space and so has been changed. You can still use a box collider if you want the visual effect of the pointer hitting the UI but be aware you will get unexpected artefacts if the Menu is moving.

编辑-这篇文章的先前版本使用了一个框碰撞器来使指针终止在UI元素上。 如果菜单在世界空间中移动,因此已被证明这既不必要,又会引起问题。 如果希望指针击中UI的视觉效果,仍然可以使用盒对撞机,但是请注意,如果移动菜单,将会得到意外的假象。

The interaction (and therefore the integration) comes in two parts:

交互(以及集成)分为两个部分:

1 We repurposed the existing XRIT Ray Interactor script — to get the base class and the methods that we needed to override. The key mechanism for integrating to the UI system is a model(i.e. set of points) that is passed to the UI raycaster which includes a list of points that define the line (the line might be a curve). We have added a method to the Interactor script to receive a model. Add this script to the pointer game object

1我们重新调整了现有XRIT Ray Interactor脚本的用途—获得了基类和我们需要重写的方法。 集成到UI系统的关键机制是传递给UI raycaster的模型(即点集),该模型包括定义线(线可能是曲线)的点列表。 我们在Interactor脚本中添加了一种方法来接收模型。 将此脚本添加到指针游戏对象

2 To get the Model, we link the new method on the Interactor script to the Results Changed event on the Straight Line Cast script on the Starightcaster daughter to the pointer game object.

2要获取模型,我们将Interactor脚本上的新方法链接到Starightcaster女儿的Straight Line Cast脚本上的Results Changed事件到指针游戏对象。

The raycaster then determines if the pointer passes through the interactable and takes the appropriate action.

然后,光线投射器确定指针是否通过可交互对象并采取适当的操作。

The model also contains a boolean for whether the Interactable should be selected. This was linked to the state of the right trigger.

该模型还包含一个布尔值,用于确定是否应选择Interactable。 这与正确触发器的状态有关。

The code we used is shown below, with no warranty whatsoever and for information only. Read the comments for how to link this to the VRTK ObjectPointer — basically you need to link the receiveRay method to the StraightCaster and the Selected and Unselected methods to the activation events — and then link the activated event of the ObjectPointer to the trigger (or whatever). As a note, we made our pointer to be always-on by going to each of the PointerElements and changing them to “Always On”. This very rough integration will only work with straight pointers (but it would not be that much work to make it work with curved ones) and we only implemented the functionality required for UI Interactions. More work would be required to make the pointer work with other XRIT interactables.

下面显示了我们使用的代码,没有任何担保,仅供参考。 阅读有关如何将其链接到VRTK ObjectPointer的注释-基本上,您需要将receiveRay方法链接到StraightCaster,将Selected和Unselected方法链接到激活事件-然后将ObjectPointer的激活事件链接到触发器(或任何其他触发器) )。 需要注意的是,通过将每个PointerElement更改为“ Always On”,我们使指针始终处于打开状态。 这种非常粗糙的集成仅适用于直指针(但要使其与弯曲指针配合工作并不多),并且我们仅实现了UI交互所需的功能。 要使指针与其他XRIT可交互对象一起工作,还需要做更多的工作。

Example — with Box Collider: satellite imagery © Mapbox
示例—使用Box Collider:卫星图像©Mapbox

Thus we have the pointer ray, that terminates correctly on the button which correctly changes state to highlighted. Press the trigger and the button is clicked and then selected. All systems working correctly. The button has an OnClicked event for integration into the business logic.

因此,我们有了指针射线,该射线正确地终止在按钮上,该按钮正确地将状态更改为突出显示。 按下触发器,然后单击并选择按钮。 所有系统均正常运行。 该按钮具有一个OnClicked事件,可以集成到业务逻辑中。

心愿单 (Wishlist)

In case anyone cares, or has even reached this far, some lessons.

万一有人在乎,甚至到现在为止,都可以从中吸取教训。

We managed to make a good VR interface using largely standard components. for that, we thank all who provided components.

我们设法使用大量标准组件制作了一个良好的VR界面。 为此,我们感谢所有提供组件的人。

But I wish:

但我希望:

1 That all undeprecated modules and packages from Unity and major players like Oculus should be URP ready out of the box. There is really no excuse. Also, that Unity did not seem to come with defaults that say “this is deprecated — use something else”. Why do I seem to have to create a be project and then change to URP, Input System, XR plugins and go around changing shaders and materials etc?

1所有Unity和主要参与者(如Oculus)不提倡使用的模块和软件包都应立即使用URP。 确实没有任何借口。 而且,Unity似乎没有默认值,即“已弃用–使用其他选项”。 为什么我似乎必须创建一个be项目,然后更改为URP,Input System,XR插件并四处更改着色器和材质等?

2 The VRTK Input mappings are really nice — but should not be necessary. This should have worked out of the box once the Input System and OVR Plugin are loaded. Unity and Oculus should be chasing each other to make that happen.

2 VRTK Input映射非常好-但不是必需的。 加载输入系统和OVR插件后,这应该可以立即使用。 Unity和Oculus应该互相追逐,以实现这一目标。

3 That in general, the maker of Interaction Frameworks (like both XRIT and VRTK) did not base their integrations around their own XR Rig and instead created a framework that is easily integrated into any Rig, so that the device providers like Oculus can the parts close to their hardware. VRTK is much better here than XRIT, the later having very close integration to their own XRcontroller entities and I cannot really see why.

3通常,交互框架的制造商(例如XRIT和VRTK)都没有基于自己的XR Rig进行集成,而是创建了易于集成到任何Rig中的框架,以便像Oculus这样的设备提供商可以靠近他们的硬件。 这里的VRTK比XRIT好得多,后者与他们自己的XRcontroller实体非常紧密地集成在一起,我不知道为什么。

4 In general, XRIT does a very good job of integrating into the other Unity Modules and should really have stopped there and specialised in providing a framework for other people to create XR Rigs, Interactors and Interactables. It obvious from the documentation that was the aim but they seem to have got lost along the way. Then, VRTK could focus their limited resources on creating good interactions and interactions without spending so much time on the plumbing, and they would get UI integration automatically.

4总的来说,XRIT在集成到其他Unity模块中做得非常好,应该真的就此止步,并专门为其他人提供创建XR装备,交互器和可交互对象的框架。 从文档中可以明显看出这是目标,但似乎一路迷路了。 然后,VRTK可以将其有限的资源集中在创建良好的交互和交互上,而不必花费太多时间在管道上,并且他们将自动获得UI集成。

5 Also in general, I wish that all of the Interaction components made fewer assumptions in their design. They all make assumptions about a state model fixed to touch and grab events. It would have been easier if they were architected around a set of customisable events (preferably unlimited), two of which just might be touch and grab. In our case, they were not.

5同样,总的来说,我希望所有交互组件在设计时都做出较少的假设。 他们都对固定为触摸和抓取事件的状态模型做出了假设。 如果围绕一组可定制的事件(最好是无限制的)来设计它们,那会更容易,其中两个事件可能只是一触即发。 就我们而言,不是。

码 (Code)

// parts copyright Runette Software Ltd, 2020. All rights reserved
// XR Interaction Toolkit copyright © 2019 Unity Technologies ApSusing UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq;using UnityEngine.XR.Interaction.Toolkit.UI;
using UnityEngine.EventSystems;
using UnityEngine.XR.Interaction.Toolkit;using Zinnia.Pointer;
using Zinnia.Cast;public class PointerInteractor : XRBaseInteractor, IUIInteractable
{[SerializeField]bool m_EnableUIInteraction = true;/// <summary>Gets or sets whether this interactor is able to affect UI.</summary>/// // Input Module for fast access to UI systems.XRUIInputModule m_InputModule;// Used by UpdateUIModel to retrieve the line points to pass along to Unity UI.static Vector3[] s_CachedLinePoints;/// <summary>The starting transform of any Raycasts.  Default value is the controller transform, or the attachTransform if it is not null.</summary>Transform m_StartTransform { get { return  attachTransform ?? transform; } }[SerializeField]LayerMask m_RaycastMask = -1;/// <summary>Gets or sets layer mask used for limiting raycast targets.</summary>public LayerMask raycastMask { get { return m_RaycastMask; } set { m_RaycastMask = value; } }int m_HitCount = 0;RaycastHit[] m_RaycastHits = new RaycastHit[1];Vector3[] m_LinePoints;bool isUISelectActive; public bool enableUIInteraction{get{return m_EnableUIInteraction;}set{if (m_EnableUIInteraction){m_InputModule.RegisterInteractable(this);}else{m_InputModule.UnregisterInteractable(this);}}}void FindOrCreateXRUIInputModule(){var eventSystem = UnityEngine.Object.FindObjectOfType<EventSystem>();if (eventSystem == null)eventSystem = new GameObject("Event System", typeof(EventSystem)).GetComponent<EventSystem>();m_InputModule = eventSystem.GetComponent<XRUIInputModule>();if (m_InputModule == null)m_InputModule = eventSystem.gameObject.AddComponent<XRUIInputModule>();}protected override void OnEnable(){base.OnEnable();if (m_EnableUIInteraction){FindOrCreateXRUIInputModule();m_InputModule.RegisterInteractable(this);}}protected override void OnDisable(){base.OnDisable();// clear linesm_HitCount = 0;if (m_EnableUIInteraction){m_InputModule.UnregisterInteractable(this);}m_InputModule = null;}public override void GetValidTargets(List<XRBaseInteractable> validTargets){}/// <summary>/// Updates the current UI Model to match the state of the Interactor/// </summary>/// <param name="model">The model that will match this Interactor</param>public void UpdateUIModel(ref TrackedDeviceModel model){model.position = m_StartTransform.position;model.orientation = m_StartTransform.rotation;model.select = isUISelectActive;int numPoints = 0;GetLinePoints(ref s_CachedLinePoints, ref numPoints);List<Vector3> raycastPoints = model.raycastPoints;raycastPoints.Clear();if (numPoints > 0 && s_CachedLinePoints != null){raycastPoints.Capacity = raycastPoints.Count + numPoints;for (int i = 0; i < numPoints; i++)raycastPoints.Add(s_CachedLinePoints[i]);}model.raycastLayerMask = raycastMask;}/// <summary>/// Attempts to retrieve the current UI Model.  Returns false if not available./// </summary>/// <param name="model"> The UI Model that matches that Interactor.</param>/// <returns></returns>public bool TryGetUIModel(out TrackedDeviceModel model){if (m_InputModule != null){if (m_InputModule.GetTrackedDeviceModel(this, out model))return true;}model = new TrackedDeviceModel(-1);return false;}/// <summary>/// This function will return the first raycast result, if any raycast results are available./// </summary>/// <param name="raycastHit">the raycastHit result that will be filled in by this function</param>/// <returns>true if the raycastHit parameter contains a valid raycast result</returns>public bool GetCurrentRaycastHit(out RaycastHit raycastHit){if (m_HitCount > 0 ){raycastHit = m_RaycastHits[0];return true;}raycastHit = new RaycastHit();return false;}/// <summary> This function implements the ILineRenderable interface and returns the sample points of the line. </summary>public bool GetLinePoints(ref Vector3[] linePoints, ref int noPoints){if (m_HitCount <= 0){return false;}else{                                                                                                                                                                                                                                                                                                                                                                                                                                                      linePoints = new Vector3[2];Array.Copy(m_LinePoints, linePoints, 2);noPoints = 2;return true;}}/// <summary> This function implements the ILineRenderable interface, /// if there is a raycast hit, it will return the world position and the normal vector/// of the hit point, and its position in linePoints. </summary>////TODO Implemet this for full functionality public bool TryGetHitInfo(ref Vector3 position, ref Vector3 normal, ref int positionInLine, ref bool isValidTarget){//float distance = float.MaxValue;//int rayIndex = int.MaxValue;//RaycastHit raycastHit;//if (GetCurrentRaycastHit(out raycastHit))  // if the raycast hits any collider//{//    position = raycastHit.point;//    normal = raycastHit.normal;//    positionInLine = rayIndex = m_HitPositionInLine;//    distance = raycastHit.distance;//    // if the collider is registered as an interactable and the interactable is being hovered//    var interactable = interactionManager.TryGetInteractableForCollider(raycastHit.collider);//    isValidTarget = interactable && m_HoverTargets.Contains(interactable);//}//RaycastResult result;//int raycastPointIndex;//if (GetCurrentUIRaycastResult(out result, out raycastPointIndex))//{//    if (raycastPointIndex >= 0)//    {//        if (raycastPointIndex < rayIndex || ((raycastPointIndex == rayIndex) && (result.distance <= distance)))//        {//            position = result.worldPosition;//            normal = result.worldNormal;//            positionInLine = raycastPointIndex;//            isValidTarget = result.gameObject != null;//        }//    }//}return isValidTarget;return true;}// // Connect this callback to the UnityEvent that shhould start the "Selected" state// e.g the VRTK ObjectPointer Activated event//public void Selected(ObjectPointer.EventData data){isUISelectActive = true;}// // Connect this callback to the UnityEvent that shhould stop the "Selected" state// e.g the VRTK ObjectPointer Deactivated event//public void UnSelected(ObjectPointer.EventData data){isUISelectActive = false;}//// Connect this to the ObjectPointer/StraightCaster ResultsChanged event to get the results of the latest ray cast//public void receiveRay(PointsCast.EventData data){m_HitCount = 1;m_LinePoints = data.Points.ToArray<Vector3>();}}

翻译自: https://medium.com/runic-software/making-a-business-oriented-vr-interface-a42e37f3bbe4

vr全景接口


http://www.taodudu.cc/news/show-2422917.html

相关文章:

  • 重新思考路易斯维尔足球品牌
  • ai人工智能_人工智能能否赢得奥运
  • 机器学习基石和机器学习技法_机器学习和洞穴寓言寓言
  • 板凳——————————————————c++(104)
  • C++PrimerPlus 第六章 分支语句和逻辑运算符 - 6.1 if语句
  • I didn't write blog yesterday night for some ineffable reasons
  • VBA操作CAD画一条直线
  • CAD绘制直线
  • cad 绘制直线 设定长度 角度
  • 机械CAD中如何设置重叠图形消隐?
  • CAD打断线条的快捷键是什么?CAD打断线条教程
  • 【AutoCAD】04.直线类命令
  • CAD中画一条直线与两个圆相切
  • cad画直角命令_CAD直线怎么画?直线命令快捷键是什么
  • Canvas 画直线
  • AutoCAD入门——直线
  • cad线加粗怎么设置_cad2016怎么把线加粗
  • cad线加粗怎么设置_CAD图形中线条如何加粗?
  • cad直线和圆弧倒角不相切_数控加工中心如何使用任意角度倒角C和倒圆角R功能的编程...
  • 直线端点画垂线lisp_AutoCAD中利用AutoLISP开发小程序,实现快速画直线对称中心线...
  • P2P继续停止...
  • 2-4 CAD基础 修剪(trim)
  • 悲剧!广电总局12月11日将封闭的网站目录!!!
  • 怎么将CAD中的两条直线拉成弧形呢?
  • VeryCD将于本月关闭 P2P历史即将终结
  • cad画直线长度与实际不符_CAD问题,画线长度不对?
  • 吊销 BTChina 营业执照”后元旦之前可能相继落马的“影视下载”网站名单
  • cad直线和圆弧倒角不相切_在cad绘制倒圆角的方法技巧步骤详解
  • 沉痛哀悼我们的电骡和BT中国联盟
  • CAD参数绘制直线(网页版)

vr全景接口_制作面向业务的VR接口相关推荐

  1. VR全景视频如何制作?能够应用在哪些行业?

    VR全景视频是现下一种新型的视频展现方式,其震撼效果无可厚非,现如今市场上面的VR全景视频也是有很多的,那么你了解VR全景视频是如何制作出来的吗?能够应用在哪些行业呢? 一.VR全景视频如何制作? 全 ...

  2. 全方位了解VR全景展示与制作

    引言: 虚拟现实(VR)技术正在以惊人的速度改变我们的生活方式和体验方式.其中,VR全景展示与制作作为虚拟现实的重要应用之一,为用户提供了身临其境的视听体验. 一.了解VR全景展示与制作 1.VR全景 ...

  3. VR全景的拍摄制作上传

    360°VR全景如何制作? 随着全景技术的逐渐发展,VR虚拟体验也是越来越常见.VR全景技术也已经逐渐应用到各个行业领域.全景摄影,全景视频等等都已经逐渐的大众化,就比如说现在的房地产行业已经推出了很 ...

  4. 酷雷曼在vr全景加盟排行如何?如何选择vr全景加盟商?

    如今的虚拟现实技术越来越成熟,vr一词反复出现在我们的视野中,由于vr技术市场正处以一片蓝海,现在众多的投资者把目光放在vr行业,因为5g时代彻底带火vr技术,因此VR技术得到快速蓬勃的发展,5G技术 ...

  5. vr全景视频如何制作? vr看房有什么好处!

    说到vr,在很早以前就已经拥有了这些技术.只是那时候只应用到娱乐场所中,因为这些技术能让人有一股身临其境的感觉.所以人们用vr全景技术能短暂避免一些烦恼从而获取幸福.随着科技越来越发达,vr全景已经不 ...

  6. 0基础学习VR全景平台篇 第65篇:VR直播-如何创建VR直播

    开启一次VR直播只需简单三步:VR直播相机连接网线并开机=>新建一个直播活动=>将直播活动的推流地址填入直播相机. 1.将鼠标移至[开始创作]菜单,点击[全景直播]. 2.进入VR直播活动 ...

  7. lightning接口_带你回看手机接口发展史:TypeC将实现大一统?

    [PConline 杂谈]手机在近几年发展飞快,从当年只要有一台大哥大就十分威风,到后来的诺基亚一统天下,再到现在人手一部智能手机,手机变更如此之快,体积越来越小,续航能力越来越强,超级快充也变成了常 ...

  8. python调用api应用接口_第三方免费快递物流查询接口平台(快递鸟)api接口调用...

    随着网购的发展,快递业也随之壮大.快递查询接口对接的需求量也越来越大,下面是对免费快递接口做的整理,并附上调用流程,分享给大家. 项目开发中,有些需求难免会用到关于快递的一些Api接口:本篇主要介绍的 ...

  9. java定义接口_一文知道Java中接口的定义

    使用interface来定义一个接口.接口定义同类的定义类似,也是分为接口的声明和接口体,其中接口体由常量定义和方法定义两部分组成.定义接口的基本格式如下: 方法:接口中的方法只有定义而没有被实现. ...

  10. rest接口_深度干货 | 测试REST服务接口

    openEA开源社区 开源,我们是认真的! 这里每天给大家呈现有价值的开源资讯,欢迎您的来稿与推荐,点击上方蓝色字,加入我们吧! 摘要:较新的BPM版本中,提供了SOAP和REST两种接口,这里我讲下 ...

最新文章

  1. jenkins-svn配置
  2. vysor原理以及Android同屏方案
  3. xy坐标转换为极坐标_CAD制图软件新手攻略:坐标系及标注坐标
  4. 手写体识别(数据挖掘入门与实践-实验11)
  5. TensorFlow学习笔记(二十一) tensorflow机器学习模型
  6. python一些方便excel行操作的函数(一)
  7. java数组排序冒泡排序_java数组常见的排序——选择排序和冒泡排序
  8. 微软开源用于大规模查找并修复漏洞的开发者工具 Project OneFuzz 框架
  9. docker 升级linux内核,docker-machine之升级linux内核
  10. mysql insert on update_我可以始终使用INSERT…ON DUPLICATE UPDATE进行简单的更新/插入吗?...
  11. win10查看所有的wifi密码。
  12. WIFI理论速度计算
  13. 计算机网络抓包分析dns,DNS抓包分析详细教程
  14. select2 api参数中文文档
  15. java 右下角_java右下角弹窗
  16. 复试21天Day 21
  17. xlsx表格用计算机公式算,excel表格数据求和与计算器不一致-excel表格用公式计算出来的数值跟计算器计算出来的......
  18. inputstream流乱码_InputStream读取文件乱码
  19. xgboost, lightgbm, catboost, 谁才是预言之战的最终赢家?
  20. ProcessStartInfo处理方法

热门文章

  1. 2×3卡方检验prism_何时应该使用非参数检验?
  2. 如何在苹果手机上进行自动化测试!!!!!可以尝试配置一下
  3. 计算机cpu架构是什么意思,「电脑小白必备」一分钟快速了解CPU
  4. 怎么用python在淘宝抢单_淘宝抢单怎么做到秒抢 你需要知道的必杀步骤
  5. office表格怎么冻结前两行_冻结Excel表格中多行或多列的方法
  6. 配置cfree 5 支持C++11
  7. vue3.0 ele-plus 与 antd-design的使用
  8. python3爬虫(1)爬取链家二手房
  9. SMP_WEIBO_2016 微博用户画像 可视化(未完成)
  10. 使用outlook及office assitans实现邮件批量发送