Handling 3D Interaction and UI Controls in Augmented Reality(在增强现实中处理3D交互和UI控件)

Follow best practices for visual feedback, gesture interactions, and realistic rendering in AR experiences.

融合视觉反馈,手势交互和逼真渲染的最佳AR体验。


Overview

Augmented reality (AR) offers new ways for users to interact with real and virtual 3D content in your app. However, many fundamental principles of human interface design are still valid. Convincing AR illusions also require careful attention to 3D asset design and rendering. The iOS Human Interface Guidelines include advice on human interface principles for AR. This project shows ways to apply those guidelines and easily create immersive, intuitive AR experiences.

This sample app provides a simple AR experience allowing a user to place one or more realistic virtual objects in their real-world environment, then arrange those objects using intuitive gestures. The app offers user interface cues to help the user understand the state of the AR experience and their options for interaction.

The sections below correspond to sections in iOS Human Interface Guidelines > Augmented Reality, and provide details on how this sample app implements those guidelines. For more detailed reasoning on each section, see the corresponding content in the iOS Human Interface Guidelines.

概述

增强现实(AR)为用户提供了与应用中的真实和虚拟3D内容交互的新方法。 但是,人机界面设计的许多基本原则仍然有效。 令人信服的AR场景也需要仔细关注3D Asset设计和渲染。 iOS人机界面指南包含有关AR人机界面原则的建议。 该项目展示了如何应用这些指导方针并轻松创建身临其境的直观AR体验。

此示例应用程序提供了一种简单的AR体验,允许用户将一个或多个真实的虚拟对象置于其真实世界的环境中,然后使用直观的手势排列这些对象。 该应用程序提供用户界面提示,以帮助用户了解AR体验的状态及其交互选项。

以下各节对应于iOS人机界面指南>增强现实中的各个部分,并提供有关此示例应用程序如何实现这些指南的详细信息。 有关每个部分的更详细推理,请参阅iOS人机界面指南中的相应内容。

Placing Virtual Objects

Help people understand when to locate a surface and place an object. The FocusSquareclass draws a square outline in the AR view, giving the user hints about the status of ARKit world tracking.

放置虚拟物品

帮助人们了解何时找到表面并放置物体。 FocusSquareclass在AR视图中绘制方形轮廓,为用户提供有关ARKit世界跟踪状态的提示。

The square changes size and orientation to reflect estimated scene depth, and switches between open and closed states with a prominent animation to indicate whether ARKit has detected a plane suitable for placing an object. After the user places a virtual object, the focus square disappears, remaining hidden until the user points the camera at another surface.

Respond appropriately when the user places an object. When the user chooses a virtual object to place, the sample app’s setPosition(_:relativeTo:smoothMovement)method uses the FocusSquare object’s simple heuristics to place the object at a roughly realistic position in the middle of the screen, even if ARKit hasn’t yet detected a plane at that location.

正方形改变大小和方向以反映估计的场景深度,并通过突出的动画在打开和关闭状态之间切换,以指示ARKit是否检测到适合放置对象的平面。 用户放置虚拟物体后,焦点正方形消失,保持隐藏状态,直到用户将相机指向另一个表面。

当用户放置对象时适当地作出响应。 当用户选择要放置的虚拟对象时,即使ARKit在那个位置没有检测到一个平面,示例应用程序的setPosition(_:relativeTo:smoothMovement)方法也会使用FocusSquare对象的简单启发式方法将对象置于屏幕中间的大致实际位置。

This position might not be an accurate estimate of the real-world surface the user wants to place the virtual object on, but it’s close enough to get the object onscreen quickly.

Over time, ARKit detects planes and refines its estimates of their position, calling the renderer:didAddNode:forAnchor: and renderer:didUpdateNode:forAnchor:delegate methods to report results. In those methods, the sample app calls its adjustOntoPlaneAnchor(_:using:) method to determine whether a previously placed virtual object is close to a detected plane. If so, that method uses a subtle animation to move the virtual object onto the plane, so that the object appears to be at the user’s chosen position while benefiting from ARKit’s refined estimate of the real-world surface at that position:

这个位置可能不是用户想要放置虚拟物体的真实世界表面的准确估计,但它足够接近以快速获取屏幕上的对象。

随着时间的推移,ARKit会检测平面并提高其位置估计值,并调用渲染器:didAddNode:forAnchor:和renderer:didUpdateNode:forAnchor:委托方法报告结果。 在这些方法中,示例应用程序调用其adjustOntoPlaneAnchor(_:using :)方法来确定先前放置的虚拟对象是否靠近检测到的平面。 如果是这样,该方法使用微妙的动画将虚拟物体移动到平面上,以便物体看起来在用户选择的位置,同时受益于ARKit在该位置对现实世界表面的精确估计:

Use anchors to improve tracking quality around virtual objects. Whenever you place a virtual object, always add an ARAnchor representing its position and orientation to the ARSession. After moving a virtual object, remove the anchor at the old position and create a new anchor at the new position. Adding an anchor tells ARKit that a position is important, improving world tracking quality in that area and helping virtual objects appear to stay in place relative to real-world surfaces. (See the sample code’s addOrUpdateAnchor() method.)

使用锚点来提高虚拟物体周围的跟踪质量。 每当你放置一个虚拟对象时,总是添加一个ARAnchor来表示它的位置和方向到ARSession。 移动虚拟对象后,移除旧位置的锚点并在新位置创建一个新锚点。 添加一个锚点告诉ARKit一个位置是重要的,提高了该区域的世界跟踪质量,并帮助虚拟对象看起来相对于真实世界的表面保持原位。 (请参阅示例代码的addOrUpdateAnchor()方法。)

User Interaction with Virtual Objects

Allow people to directly interact with virtual objects using standard, familiar gestures. The sample app uses one-finger tap, one- and two-finger pan, and two-finger rotation gesture recognizers to let the user position and orient virtual objects. The sample code’s VirtualObjectInteraction class manages these gestures.

In general, keep interactions simple. When dragging a virtual object (see the translate(_:basedOn:infinitePlane:) method), the sample app restricts the object’s movement to the two-dimensional plane it’s placed on. Similarly, because a virtual object rests on a horizontal plane, rotation gestures (see the didRotate(_:) method) spin the object around its vertical axis only, so that the object remains on the plane.

Respond to gestures within reasonable proximity of interactive virtual objects. The sample code’s objectInteracting(with:in:) method performs hit tests using the touch locations provided by gesture recognizers. By hit testing against the bounding boxes of the virtual objects, the method makes it more likely that a user touch will affect the object even if the touch location isn’t on a point where the object has visible content. By performing multiple hit tests for multitouch gestures, the method makes it more likely that the user touch affects the intended object:

用户与虚拟对象的交互

允许人们使用标准,熟悉的手势直接与虚拟对象交互。示例应用程序使用单指轻拍,单指和双指锅,以及双指旋转手势识别器来让用户定位和定位虚拟对象。示例代码的VirtualObjectInteraction类管理这些手势。

一般而言,保持交互简单。拖动虚拟对象时(请参阅translate(_:basedOn:infinitePlane :)方法),示例应用程序将对象的移动限制为其放置的二维平面。同样,由于虚拟物体停留在水平面上,旋转手势(请参阅didRotate(_ :)方法)仅将物体围绕其垂直轴旋转,以使物体保持在平面上。

在合理接近交互式虚拟对象的情况下对手势做出响应。示例代码的objectInteracting(with:in :)方法使用手势识别器提供的触摸位置执行命中测试。通过针对虚拟对象的边界框进行命中测试,该方法使得即使触摸位置不在对象具有可见内容的点上,用户触摸也更有可能影响对象。通过对多点触控手势执行多个命中测试,该方法使得用户触摸更有可能影响预期的对象:


Consider whether user-initiated object scaling is necessary. This AR experience places realistic virtual objects that might naturally appear in the user’s environment, so preserving the intrinsic size of the objects aids realism. Therefore, the sample app doesn’t add gestures or other UI to enable object scaling. Additionally, by not including a scale gesture, the sample app prevents a user from becoming confused about whether a gesture resizes an object or changes the object’s distance from the camera. (If you choose to enable object scaling in your app, use a pinch gesture recognizer.)

Be wary of potentially conflicting gestures. The sample code’s ThresholdPanGestureclass is a UIPanGestureRecognizer subclass that provides a way to delay the gesture recognizer’s effect until after the gesture in progress passes a specified movement threshold. The sample code’s touchesMoved(with:) method uses this class to let the user smoothly transition between dragging an object and rotating it during a single two-finger gesture:

考虑用户启动的对象缩放是否必要。这种AR体验放置了可能自然出现在用户环境中的逼真的虚拟对象,因此保留对象的固有尺寸有助于保持真实感。因此,示例应用程序不会添加手势或其他UI来启用对象缩放。此外,通过不包含比例手势,示例应用程序可防止用户对手势调整对象大小或改变对象与相机的距离感到困惑。 (如果您选择在应用中启用对象缩放,请使用捏手势识别器。)

警惕潜在的冲突手势。示例代码的ThresholdPanGestureclass是一个UIPanGestureRecognizer子类,它提供了一种方法来延迟手势识别器的效果,直到手势正在进行超过指定的移动阈值。示例代码的touchesMoved(with :)方法使用此类来让用户在单个双指手势中拖动对象并旋转它之间平滑过渡:

Make sure virtual object movements are smooth. The sample code’s setPosition(_:relativeTo:smoothMovement) method interpolates between the touch gesture locations that result in dragging an object and a history of that object’s recent positions. By averaging recent positions based on distance to the camera, this method produces smooth dragging movement without causing the dragged object to lag behind the user’s gesture:

确保虚拟物体移动平稳。 示例代码的setPosition(_:relativeTo:smoothMovement)方法在导致拖动对象的触摸手势位置和该对象最近位置的历史记录之间插值。 通过基于距相机的距离平均最近的位置,该方法产生平滑的拖动运动,而不会导致被拖动的物体滞后于用户的手势:

Explore even more engaging methods of interaction. In an AR experience, a pan gesture—that is, moving one’s finger across the device’s screen—isn’t the only natural way to drag virtual content to a new position. A user might also intuitively try holding a finger still against the screen while moving the device, effectively dragging the touch point across the AR scene.

The sample app supports this kind of gesture by calling its updateObjectToCurrentTrackingPosition() method continually while a drag gesture is in progress, even if the gesture’s touch location hasn’t changed. If the device moves during a drag, that method calculates the new world position corresponding to the touch location and moves the virtual object accordingly.

探索更吸引人的互动方式。 在AR体验中,平移手势 - 即将手指移动到设备的屏幕上 - 并不是将虚拟内容拖到新位置的唯一自然方式。 用户也可以在移动设备时直观地尝试将手指保持在屏幕上,有效地将触摸点拖过AR场景。

即使手势的触摸位置没有改变,示例应用也会在拖动手势正在进行时通过不断调用其updateObjectToCurrentTrackingPosition()方法来支持这种手势。 如果设备在拖动过程中移动,该方法将计算与触摸位置相对应的新世界位置并相应地移动虚拟对象。

Entering Augmented Reality

Indicate when initialization is occurring and involve the user. The sample app shows textual hints about the state of the AR session and instructions for interacting with the AR experience using a floating text view. The sample code’s StatusViewController class manages this view, showing transient instructions that fade away after allowing the user time to read them, or important status messages that remain visible until the user corrects a problem.

输入增强现实

指示何时进行初始化并涉及用户。 示例应用程序显示有关AR Session状态的文本提示以及使用浮动文本视图与AR体验交互的说明。 示例代码的StatusViewController类管理此视图,显示在允许用户读取它们后即刻消失的瞬态指令,或直到用户纠正问题时才显示的重要状态消息。

Handling Problems

Allow people to reset the experience if it doesn’t meet their expectations. The sample app has a Reset button that’s always visible in the upper-right corner of the UI, allowing a user to restart the AR experience regardless of its current state. See the restartExperience()method in the sample code.

Offer AR features only on capable devices. The sample app requires ARKit for its core functionality, so it defines the arkit key in the UIRequiredDeviceCapabilities section of its Info.plist file. When deploying the built project, this key prevents installation of the app on devices that don’t support ARKit.

If your app instead uses AR as a secondary feature, use the isSupported method to determine whether to hide features that require ARKit.

处理问题

如果它不符合他们的期望,允许人们重置体验。 示例应用程序具有重置按钮,该按钮始终在用户界面的右上角可见,允许用户重新启动AR体验,而不管其当前状态如何。 请参阅示例代码中的restartExperience()方法。

仅在有能力的设备上提供AR功能。 示例应用程序需要ARKit的核心功能,因此它在其Info.plist文件的UIRequiredDeviceCapabilities部分中定义了arkit密钥。 部署构建的项目时,此键可防止在不支持ARKit的设备上安装应用程序。

如果您的应用改为使用AR作为辅助功能,请使用isSupported方法确定是否隐藏需要ARKit的功能。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容

  • 我是一个20岁的成年人了,我选择朋友的宗旨是可以聊的很开心,相处得来,那就是朋友。没有什么比较。就像每个孩子在妈妈...
    瑞瑞瑞瑞z阅读 771评论 1 1
  • 孤独是一个很可怕的东西,大多数人都难以忍受孤独,所以我们渴望爱,渴望合群。可是这和我今天说的主题有什么关系呢...
    陌上阡虹阅读 495评论 0 1
  • 传递年的味道,构筑爱的怀抱,播种梦的种子,让梦想的光芒,照亮每个新娃娃!大家好!我们新父母成长学院年课堂“逐...
    H011常利锋阅读 629评论 2 3
  • 《我喜爱一切不彻底的事物》 总喜欢把自己定位成一个执着于思想力的人,慢慢想和那些文艺的东西告别。但当我在图书馆偶遇...
    Lynn_L阅读 188评论 0 1