建立增强现实经验简介

增强现实(AR)将数字内容覆盖到物理世界,创造互动体验,将现实与虚拟对象融合。苹果的RealityKit框架为开发者提供高级、表演的API,为iOS构建AR应用。本文扩展了基础,包括设置、实体的组件架构、用户互动、动画、物理、协作和优化。 最终,你会实际了解如何使用Swift和RealityKit创建光滑的AR体验。

启动:项目设置和要求

要开发与RealityKit的AR应用程序,您需要Xcode 13或以后,一个带有A9芯片或更新器(iPhone SE,6s,以及后来;iPads 5th gen和后来)的物理iOS设备,以及一个用于测试的苹果开发者账户. iOS模拟器不支持相机或传感器数据,因此真-device测试是必需的.

创建一个新的 Xcode 项目并选择 增强现实 App 模板。 根据您的偏好选择 SwiftUI 或 UIKit 。 现实 Kit 与两者无缝。 该模板提供了 和基本场景设置 。

或者,您可以通过导入框架, 手动将RealityKit添加到已有的工程中:

import RealityKit
import ARKit

确保 [ [FLT: 0]] NSCameraUsage Description [[FLT: 1] 设置在您的 [[FLT: 2] 中 – 一个用户友好的字符串,解释为什么应用程序需要相机访问 。

详见苹果公司RealityKit文档ARKit文档.

了解实体的“组成部分”系统

RealityKit 使用了 实体 架构,这是构建场景的根本。 是一个容器,它持有组件。组件定义了实体的行为、外观、物理和其他属性。例如,一个 定义了3D网格,一个] 处理位置/旋转/尺度,和一个 使物理模拟成为可能。

这种模块化方法使得复杂对象很容易编译。您创建实体,附加组件,并按层次排列。场景的根部是(通常为]],它将虚拟内容与ARKit检测到的真世界位置联系起来。

创建锁定和添加内容

最常见的锚是平面锚,它把内容附在水平或垂直表面。这里是怎样在任何公认的平面上放置3D模型:

// Load a USDZ model
guard let model = try? ModelEntity.load(named: "robot") else { return }

// Create an anchor on any horizontal plane
let anchor = AnchorEntity(plane: .horizontal, classification: .any, minimumBounds: [0.2, 0.2])

// Attach the model to the anchor
anchor.addChild(model)

// Add the anchor to the ARView’s scene
arView.scene.addAnchor(anchor)

您也可以使用 或使用 或 ] ,在特定世界位置创建锚点,或在检测到的图像或面孔上附加内容。

建立符合现实的初级AR场景

除了简单的模型放置, 您还需要管理 AR 视图生命周期。 在 UIKit app中, 在视图控制器中添加一个 [[FLT: 13] ] :

class ViewController: UIViewController {
 @IBOutlet var arView: ARView!

 override func viewDidLoad() {
 super.viewDidLoad()
 arView.session.delegate = self
 // Configure session
 let config = ARWorldTrackingConfiguration()
 config.planeDetection = [.horizontal, .vertical]
 arView.session.run(config)
 loadContent()
 }

 func loadContent() {
 // Create and add anchors
 }
}

对于SwiftUI,将]的桥架嵌入SwiftUI的等级.

用户交互:手势和击打

要让您的 AR 应用程序交互, 您需要处理用户的自带、 拖曳和旋转。 RealityKit 提供了 hit testing 以识别用户触及的哪个实体 。

磁带到位置或交互

在手势处理器中,拨打[],以取回指下的实体:

arView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap(_:))))

@objc func handleTap(_ sender: UITapGestureRecognizer) {
 let location = sender.location(in: arView)
 if let entity = arView.entity(at: location) {
 // Scale the entity
 var transform = entity.transform
 transform.scale *= 1.2
 entity.move(to: transform, relativeTo: entity.parent, duration: 0.3, timingFunction: .easeInOut)
 } else {
 // Place a new object at the tapped location
 placeObject(at: location)
 }
}

func placeObject(at screenPoint: CGPoint) {
 let results = arView.raycast(from: screenPoint, allowing: .estimatedPlane, alignment: .any)
 guard let result = results.first else { return }
 let anchor = AnchorEntity(world: result.worldTransform)
 let box = ModelEntity(mesh: .generateBox(size: 0.1), materials: [SimpleMaterial(color: .blue, isMetallic: false)])
 anchor.addChild(box)
 arView.scene.addAnchor(anchor)
}

相对于真实世界表面的雷射比实体在想要将内容放入平面时的撞击更可靠。 请为此使用 [[FLT: 21]] 。

拖动和旋转手势

为允许拖曳,请附加],并更新实体在平面上的位置。旋转时使用:

let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
arView.addGestureRecognizer(panGesture)

@objc func handlePan(_ sender: UIPanGestureRecognizer) {
 let location = sender.location(in: arView)
 guard let entity = arView.entity(at: location) else { return }
 guard let parent = entity.parent as? HasAnchoring else { return }
 // Translate the entity in the anchor’s local plane
 let translation = sender.translation(in: arView)
 // ... (convert to 3D movement)
}

为了实现强有力的执行,考虑使用RealityKit的包件,或使用iOS 16+中的手势属性。

高级特征:动画、物理和协作

动画

RealityKit 既支持骨骼动画(来自USDZ文件),也支持基于属性的动画。要在有动画资源的模型上触发内建动画:

guard let model = try? ModelEntity.load(named: "dancing_character") else { return }
model.playAnimation(model.availableAnimations[0].repeat(duration: .infinity), transitionDuration: 0.5, startsPaused: false)

您也可以使用先前看到的 ] 方法进行动画变换、不透明或自定义参数。对于复杂的序列,请使用 或 ]。

物理模拟

附加一个],以便实现重力、碰撞和力:

let box = ModelEntity(mesh: .generateBox(size: 0.1), materials: [SimpleMaterial(color: .red, isMetallic: false)])
box.position = [0, 0.5, 0] // above a plane

let physicsBody = PhysicsBodyComponent(
 massProperties: .default,
 material: .generate(staticFriction: 0.8, dynamicFriction: 0.5, restitution: 0.3),
 mode: .dynamic
)
box.components.set(physicsBody)

let collision = CollisionComponent(shapes: [.generateBox(size: [0.1, 0.1, 0.1])])
box.components.set(collision)
// Add box to anchor anchor.addChild(box)

盒子会掉到飞机上, 并应对碰撞。 静止物体( 如墙壁) 应有 [ [FLT: 34] ]] 。

年度报告合作会议

使用 ARKit 的协作会话,多个设备可以共享相同的 AR 世界。 通过设置会话的协作选项来启用协作:

config.collaborationEnabled = true
arView.session.run(config)

通过网络框架(例如多端连接)将 发送给其他同伴。每个设备的RealityKit场景仍然同步。这对多人游戏或共享设计审查来说是理想的。

优化平滑AR经验的性能

AR应用软件要求高帧率(60 fps)以避免运动疾病。

  • 使用低 ⁇ poly模型并优化了USDZ文件. 保持顶点计数低,并使用压缩纹理(KTX或PNG).
  • 限制场景中实体的数目。使用调试计数。
  • 通过使用instance – 跨多个实体共享同一模式,将绘图调用[最小化.
  • ]在旧设备上用]来渲染质量].
  • 使用]型号加载[]防止阻断主线程。装入型号在背景队列中,待准备时呈现.
  • 管理AR会话生命周期:当应用程序进入背景时,拨打,并在前方重运行配置.

详细指导见苹果公司创造出一种隐含的AR经验测试和解决问题你的AR经验.

设计直观 AR 接口

AR的用户体验与传统应用不同。遵循这些原则:

  • 沙面检测反馈:可视化被检测的飞机,并带有网格或大纲,这样用户就知道将物体放置在哪里.
  • 装置应感觉自然:使用直接操纵(拖动,拖动,捏动)而不是抽象控制.
  • 提供视觉提示[:在用户指向有效平面时,突出显示交互实体或显示十字架.
  • 手提照明[:RealityKit可以自动估计真实的世界光线,并将其应用到虚拟对象上. 使用来调整强度.
  • 在各种环境中的试验[:不同的照明,纹理,和房间大小影响AR跟踪. 优化平均条件.

调试和测试 AR 应用程序

Real desvice 测试是不可谈判的。 使用 Xcode 的 [[FLT: 0] ARKit 调试特性 :

  • 启用 [FLT: 42] ,以显示特征点、世界源和物理线框。
  • 使用 ] 日志查看何时检测到表面 。
  • 添加一个 ] ,以监视跟踪状态和错误.
  • 测试多设备代(如iPhone 8 vs. iPhone 14 Pro),以测量性能.

对于自动化的UI测试,可以模拟AR数据,但人工测试对于准确性仍然是必不可少的.

结论

RealityKit 总结了AR开发的复杂性,但构建一个抛光的经验需要关注实体架构、用户互动、性能和设计。 通过将覆盖的技术 — — 从场景设置和手势处理到物理和协作 — — 结合起来,你能够创建AR应用程序,让用户参与进来,并充分利用iOS硬件的全部潜力。 保持苹果公司不断发展的AR框架的时尚,并始终在真实设备上进行测试,以确保无缝和浸润体验。