首页 > 解决方案 > 如何在 SwiftUI 中使用 ARView?

问题描述

我想在基于 SwiftUI 的应用程序中使用这个 Apple 演示项目中的代码:

https://developer.apple.com/documentation/arkit/content_anchors/capturing_body_motion_in_3d

我读过这篇文章:https ://medium.com/dev-genius/implementing-ar-in-swiftui-without-storyboards-ec529ace7ab2

在尝试将两者结合起来之后,我无法让 RealityKit 工作。

这是我想在 SwiftUI 视图中表示的 ViewController:

import UIKit
import SwiftUI
import RealityKit
import ARKit
import Combine

class ViewController: UIViewController, ARSessionDelegate {

@IBOutlet var arView: ARView!

// The 3D character to display.
var character: BodyTrackedEntity?
let characterOffset: SIMD3<Float> = [0, 0, 0] // Offset the character by one meter to the left
let characterAnchor = AnchorEntity()

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    arView.session.delegate = self
    
    // If the iOS device doesn't support body tracking, raise a developer error for
    // this unhandled case.
    guard ARBodyTrackingConfiguration.isSupported else {
        fatalError("This feature is only supported on devices with an A12 chip")
    }
    
    // Run a body tracking configration.
    let configuration = ARBodyTrackingConfiguration()
    arView.session.run(configuration)
    
    arView.scene.addAnchor(characterAnchor)
    
    // Asynchronously load the 3D character.
    var cancellable: AnyCancellable? = nil
    cancellable = Entity.loadBodyTrackedAsync(named: "character/robot").sink(
        receiveCompletion: { completion in
            if case let .failure(error) = completion {
                print("Error: Unable to load model: \(error.localizedDescription)")
            }
            cancellable?.cancel()
        }, receiveValue: { (character: Entity) in
            if let character = character as? BodyTrackedEntity {
                // Scale the character to human size
                character.scale = [1.0, 1.0, 1.0]
                self.character = character
                cancellable?.cancel()
            } else {
                print("Error: Unable to load model as BodyTrackedEntity")
            }
        })
}

func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
    for anchor in anchors {
        guard let bodyAnchor = anchor as? ARBodyAnchor else { continue }
        
        // Update the position of the character anchor's position.
        let bodyPosition = simd_make_float3(bodyAnchor.transform.columns.3)
        characterAnchor.position = bodyPosition + characterOffset
        // Also copy over the rotation of the body anchor, because the skeleton's pose
        // in the world is relative to the body anchor's rotation.
        characterAnchor.orientation = Transform(matrix: bodyAnchor.transform).rotation
        
        if let character = character, character.parent == nil {
            // Attach the character to its anchor as soon as
            // 1. the body anchor was detected and
            // 2. the character was loaded.
            characterAnchor.addChild(character)
        }
    }
}
}

我能够表示更简单的 UIViewController,例如:

struct ImagePicker: UIViewControllerRepresentable {
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
    code
}

func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
    code
}
}

但是,我正在努力为 ARView 复制这个。我是一个初学者,如果这个问题有错误,我很抱歉,任何可能有帮助的文章的指针都会很棒。提前致谢。

标签: swiftswiftuiuiviewcontrollerarkitrealitykit

解决方案


推荐阅读