iosswiftarkitswift-package-managerrealitykit

How to load a Reality Composer Pro Scene into an ARView for iOS


As question states, am trying to load a file called TestScene.usda, created in Reality Composer Pro, using the ModelEntity.load method, into an ARView within an iOS (not VisionOS!) project, so it can be attached to a horizontal anchor. Documentation for how to do this seems thin on the ground.

I have my RCP project imported as a Swift package using the following structure and the package has been added to the target as a Library in Xcode:

file structure in Xcode Navigator

Note since taking this screenshot, I have added a 'Resources' folder to 'Sources', containing a dummy file, and referenced this in the Package manifest, so that Bundle.module works correctly and doesn't throw an inaccessible due to internal protection level error (a SPM quirk apparently)...

Code as follows.

import SwiftUI
import RealityKit
import ARKit
import RealityKitContent

struct ContentView : View {

    var body: some View {
    
        ARViewContainer().edgesIgnoringSafeArea(.all)
    
    }

}

struct ARViewContainer: UIViewRepresentable {

    typealias UIViewType = ARView

    func makeUIView(context: Context) -> ARView {
    
        let arView = ARView(frame: .zero)
    
        let arConfiguration = ARWorldTrackingConfiguration()
        arConfiguration.planeDetection = [.horizontal]
        arView.session.run(arConfiguration)
    

        // this isn't working, can't find file
        let model = try! ModelEntity.loadModel(named: "TestScene.usda", in: realityKitContentBundle)


        let anchor = AnchorEntity(.plane(.horizontal, classification: .any, minimumBounds: SIMD2<Float>(0.2, 0.2)))
    
        anchor.children.append(model)
    
        arView.scene.anchors.append(anchor)
    
        return arView
    }

    func updateUIView(_ uiView: ARView, context: Context) {}
}

#Preview {
ContentView()
}

Running the app returns an error, saying it can't find TestScene.usda. Not sure if I am using the right method for this task, I'm naming things incorrectly, I'm missing something to do with how Swift Package Manager works, or something else. Any help appreciated!


Solution

  • Don't use the .loadModel(named:in:) loader because you are most likely trying to load an Entity, not a ModelEntity. Also, you don't need to specify the file extension.

    let scene = try! Entity.load(
        named: "TestScene", in: realityKitContentBundle
    )
    print(scene)  // full hierarchy with names in console
    

    If you need to get a ModelEntity from the hierarchy, use .findEntity(named:) instance method.

    let model = scene.findEntity(
        named: "your.model.entity.name"
    ) as! ModelEntity