在VR里建房子有什么神奇的地方。想象一下能够装配无重量汽车发动机,安排动态虚拟工作空间,或创造想象的城堡与无限的砖块。安排或组装虚拟对象是跨一系列体验的常见场景,特别是在教育方面,金宝搏让球企业,以及工业培训——更不用说桌面和实时战略游戏了。

想象一下能够装配无重量汽车发动机,安排动态虚拟工作空间,或创造想象的城堡与无限的砖块。点击微博为我们的最新交互冲刺,我们探索如何构建和堆积相互作用能感觉到无缝的、反应敏捷的,稳定。我们如何,堆栈,在保持完整物理模拟的细微差别和丰富性的同时,快速准确地组装虚拟对象?查看下面的结果或从188bet让球跳跃运动画廊.

挑战

徒手操作物理模拟的虚拟对象是一项极其复杂的任务。高级手动物理层188bet让球跳跃运动交互引擎使抓取和释放虚拟对象的基本元素感到自然。这本身已经是一个壮举的工程和交互设计。

尽管如此,精确的旋转,安置,和堆叠的物理支持对象-虽然非常可能-采取灵活的触摸。特别是叠加就是一个很好的例子。


堆放在VR不应该感觉像炸弹拆除。

当我们在物理世界中堆叠对象时,通过我们的触觉,我们对塔楼稳定性的许多方面都保持着跟踪。把一个块放在一个物体塔上,我们何时何地举行块使接触结构。在那一瞬间,我们感到实际的身体阻力。这种持续的信息流允许我们无缝地调整我们的运动和反馈回路中的力的应用——所以我们不会使塔不平衡。

在VR中解决这些问题的最简单方法是禁用物理并简单地移动对象网格。这种成功消除意外碰撞对象和其他人,还有意外的轻触。


重力和惯性被禁用,我们可以随心所欲地组装积木。但是看起来还是很奇怪!!

然而,这个解决方案远非理想,精确旋转,安置,而对准仍然具有挑战性。此外,在虚拟对象上禁用物理使得与虚拟对象的交互远不那么引人注目。在VR/AR中,物理模拟虚拟交互具有先天的丰富性,只有当您能够赤手空拳时才会放大这种丰富性。

可部署脚手架

最好的VR/AR交互通常将真实世界的线索与媒体的独特可能性结合起来。研究如何简化装配在物质世界,我们观察了一些东西,比如尺子和测量带以便对齐,以及脚手架的概念。一种临时结构,用来支撑建筑材料.


可抓取网格是平面屏幕3D应用的共同特征。即使在VR中,我们也可以看到早期的例子,比如Google中非常好的实现.

VR中的可部署框架允许快速创建物理规则(暂时)不适用的交互空间。点击微博然而,而不是用网格覆盖整个世界,我们提出的想法使用它们作为离散体积工具。这将是暂时的,可调整大小的三维网格,这将有助于创建虚拟对象的程序集-一个可部署的脚手架!当对象被放置在网格中时,它们会卡到位,被一个物理弹簧夹住,在整个交互过程中保持物理模拟。一旦用户完成了组装,他们可以停用网格。这个释放弹簧和返回的对象不受约束的物理模拟。

创建这个脚手架系统我们需要建立两个组件:(1)一个可部署的,可调整的,可抓拍的3D网格,以及(2)要组装的对象的示例集。当我们进一步调查这个概念很明显,网格本身需要相当多的工程,特别是对于一个冲刺时间。

生成3D网格

构建以Scaffold交互为中心的可视网格非常简单——使用简单的预制件作为模板,实例化一个表示网格点的3D对象数组。为此,我们创建了一个ScaffoldGridVisual类。我们保持视觉脚手架的电网特性和组织单独的交互式功能的灵活性。在此,我们公开了基本参数,如点网格的比例和每个网格单元以世界单元表示的大小。

但是,虽然网格点阵列很容易创建,很明显,我们需要从一开始就进行优化。因为我们希望能够动态地改变脚手架的尺寸,我们可能很多人/支架(可能有多个支架/现场)。因此,在这种情况下,简单的静态批处理不是优化路径。

这使得创建一个定制的GPU实例着色器来呈现Scaffold网格中的点是值得的。这种类型的重复渲染相同的对象是伟大的放到GPU-它节省CPU周期和保持我们的帧率高。对于安装,我们只需要确保网格点网格的预制件具有使用GPU实例着色器的材料。

在开发的早期阶段,它有助于区分颜色点。由于网格将动态调整大小,颜色有助于识别我们正在破坏和重新创建的东西或者我们的点顺序是否有序。(而且很漂亮,我们喜欢彩虹的东西。)

基于着色的网格悬停支持

在我们的工作中,我们努力使尽可能多的事情对我们的行为产生反应——提高存在感和魔力,使虚拟现实成为如此美妙的媒介。VR缺乏我们在物理世界中依赖的许多深度线索,因此,反应性对于增强我们的本体感觉也很重要。我们对身体不同部位的相对位置的感觉)。

记住这一点,我们并没有仅仅停留在做一个立方体的网格上。由于我们使用自定义着色器渲染网格点,我们可以向着色器中添加一些特性来帮助用户更好地理解他们手的位置和深度。

在着色器中,我们为悬停位置添加3D矢量。当我们渲染网格数组中每个立方体的每个顶点时,我们可以根据每个顶点离悬停位置的距离来缩放它的位置。然后,在我们ScaffoldGridVisual类,我们可以使用API来获得指尖的188bet让球位置跳跃运动,使用它来设置自定义的值“HoePo位置”为我们的网格点数据集变量的材料。我们还可以在着色器中使用相同的悬停位置来基于相同的距离提升顶点的颜色。

结果是,当你的手靠近时,我们的网格点将增长和发光——使它更加响应和易于使用。

保存对象位置

随着网格的视觉部分正在进行中,现在是构建交互特性的时候了。为此,我们创建了一个ScaffoldGridInteraction类,该类位于预制层次结构中的SaffoldGridVisual类旁边。这个类有两个主要职责:维护一个记录,记录哪些对象被放置在哪个网格位置,当物体悬停时,找到离它最近的网格位置。

对于当前在脚手架中的对象及其网格位置的记录,在类中创建一个简单的Dictionary变量。这个拥有Vector3存储网格位置对象占据,以及ScaffoldBlockData数据类型。scaaffoldBlockData是一个自定义结构,它保存我们需要了解的每个对象:

  • 其变换
  • 它相对于网格父变换的本地位置
  • 局部旋转

这里最酷的部分是当脚手架空时,《词典》也是如此。它只需要为每个对象提供一个条目——这意味着当Scaffold中没有对象时,我们不必拥有大型的空数据数组。当对象被放置时,向字典添加条目,当对象被再次抓取时,删除条目。

使Scaffold-Reactive块和他们的鬼魂

创建对象,可以放在(对齐)我们的新网格始于一个InteractionBehaviour组件添加到我们的一个块模型。结合交互引擎,这处理了使对象可抓取的重要任务。为了增强块与网格交互的能力,我们创建并添加了另一个Monobehaviour组件,我们称之为ScaffoldBeh.ur。这种行为处理尽可能多的屏蔽一些逻辑的网格类呆那么复杂和易于使用的(是的,这是一个词)。

就像网格本身一样,我们已经学会了思考交互以及交互本身的启迪。脚手架行为处理交互逻辑,例如当我们抓取时改变物理设置,地点,释放或放下我们的积木。但是,当块位于网格中时,这个类还创建并管理块的幽灵。脚手架行为:

  1. 当块被抓取并进入网格的盒式碰撞器时,生成透明鬼模型。
  2. 将幽灵放置在离抓握手最近的网格位置
  3. 将幽灵旋转到相对于网格的块最近的正交旋转
  4. 检查幽灵是否与网格中已经存在的任何块相交,如果是这样,鬼的颜色变化。

当网格中未抓住块时,它被放置和旋转类似于网格和鬼被摧毁。另外我们添加另一个类,脚手架,以处理触发的各种外观更改——悬停,抓握,和将块。(稍后再详细介绍。)

使用交互引擎句柄调整网格大小

通过构建手柄来抓取和拖动,用户可以调整脚手架的大小以适合特定区域。我们创建了具有交互引擎行为的球形句柄,我们限制了它们控制轴的运动。ScaffoldGridVisual类引用这些句柄。当它们被拖动时,ScaffoldGridVisual重建网格动态。

当这种情况发生时,ScaffoldGridVisual检查字典从ScaffoldGridInteraction类是否有块网格点作为网格点的创建或销毁。如果是这样,根据需要调用该块的ScaffoldBeh.ur类中的AddBlockToGrid()或RemoveBlockFromGrid()方法。

这个有价值的功能可以解锁各种有趣的和紧急的交互。这种方式,如果用户在脚手架中放置块并拖动句柄以使网格更小,块释放,丢弃它们。相反,如果手柄被拖动以使网格变大,在那些网格点处放置了块,然后街区又重新回到原来的位置!!

小部件阶段,国家,形状

现在我们有一个可调整大小的3D网格,在将鬼影对象位置捕捉到位之前能够显示鬼影对象的位置,现在是将这个功能捆绑到小部件中的时候了。我们希望能够使用多个脚手架,并且能够放弃脚手架小部件,让它在最近的表面活跃起来,自动对齐,并在着陆时自动扩展手柄。(呸!管理这个高级功能带来的所有状态更改,我们创建了一个Scaffold类以位于层次结构的顶部并控制其他类。

对于这个功能,我们有一个具有四个状态的简单状态机:

  • 固定:脚手架的所有特征都是隐藏的,除了它的图标。
  • 举行:显示脚手架的网格和句柄。我们运用逻辑来寻找合适的表面。
  • 着陆:当脚手架放手,它动画和对齐到最近的表面。
  • 部署:这是主要的,活动状态的脚手架网格及其处理。

顶级Scaffold类引用了三个类——ScaffoldGridInteraction,scaaffoldGridVisual,和ScaffoldHandle。它的有限状态机根据需要控制状态改变时所有这些类的激活和禁用。脚手架组件的转换,连同它的所有子转换及其组件,然后拖到预设文件夹成为我们脚手架部件。

完成小部件的层次结构显示了上图中的类如何在Unity场景中坐在一起。

用于锚阶段是网格的完全收缩状态时可能被附加到一个浮动的手菜单槽或放置在环境,准备被接走在这种状态下,我们将小部件简化为3D图标,只有三个彩色的球体和一个较大的白色锚球。

一旦你拿起图标小部件,我们进入了等待/放置状态。图标成为具有完整特性的小部件,用它的红色,绿色和蓝色轴把手收回。握着它,我们从窗口小部件中搜索合适的放置表面(通过层定义)。旋转小部件可以瞄准raycast。

当一个注册,我们显示扩展的小部件的一个幻影版本,对齐到目标表面。在指向一个可行的表面时放开小部件,使小部件动画到其目标位置,然后自动展开轴,生成一个三维支架。

部署的小部件需要几个特性:通过推动或抓取轴手柄来调整每个轴的大小的能力,一种把整个脚手架捡起来放到其他地方的方法,以及使支架失活/重新激活的能力。

小部件本身的形状经过了几次迭代,从测量磁带和其他手持建筑辅助工具以及基于软件的转换小工具中得到灵感。我们磨练的重要的直接交互相应轴处理(红、绿色,蓝色)锚杆(白色),以及白色住宅的隐含方向性。

有色轴手柄可以推动或抓取并拖动:

整个小部件和支架可以捡起,抓住更大的白色锚处理搬迁。这个暂时返回小部件控股/放置状态和raycasts新的可行的目标位置。

和电影的一个开关可以收回和整个轴支架失效:

现在我们终于到了有趣的部分——把东西堆起来,然后把它们打倒!网格单元大小是可配置的,并且被扩展为手感良好且易于管理——比Lego块大,比砖头小。我们建模了一些简单的形状,并创建了一些倾斜的环境来设置和拆卸程序集。然后我们致力于在启示和可视化提示之间取得平衡,这将帮助用户快速准确地创建程序集,而不会感到不知所措。

当你的手靠近任何障碍物时,它的颜色稍微变浅,由接近驱动。当你选择一个明亮的辉光。它将发射强调,使“抓取”状态非常清楚:

当你给电网带来一块了,白色ghost版本出现,显示最近的可行位置和旋转。当鬼魂是白色的时候释放这个块将会把它卡到位。如果鬼相交与一个被占领的空间,鬼变红。当幽灵是红色时释放块不会简单地将块卡入网格,让它从你手中掉下来。

一块拍成网格,凹槽在角落里活跃起来,以强调它们被脚手架固定住的感觉。当关闭网格的杠杆被翻转并且脚手架轴收缩时,块缺口填充,块返回到正常静止状态。

最后一块,也许是最重要的,在整个互动过程中都在调谐肉体的感觉。供参考,以下是我们在块体被卡入脚手架后禁用物理时所看到的情况。

与区块的交互(或缺少交互)突然感到空洞和不令人满意。突然切换规则的互动从碰撞到non-colliding感觉不一致。也许,如果块放在网格中时变成了鬼影,这种变化不会太刺耳……但是如果我们添加弹簧并保持块体的可碰撞性,会发生什么呢??

好多了!现在,它感觉更像是网格是一个结构化的力场,保持块在适当的位置。然而,由于块还相互碰撞,当组件受到强烈干扰时,当弹簧试图将它们推回位置时,这些块可以相互抵触。

幸运的是,因为我们在VR中,我们可以简单地使用层来设置网格中的块,以便只与手碰撞,而不是彼此碰撞。

这感觉像是在整个交互过程中保持物理性的正确平衡,而不会因为碰撞混乱而牺牲速度或准确性。现在是时候玩我们的街区!!





图片来源:跳跃运动,188bet让球卡斯托克培养基,谷歌Sunghoon Jung史诗游戏

这篇文章最初发表的删节版本道托VR.一中文版也有。