RealityKit – 如何从 USDZ 文件向加载的 ModelEntity 添加动作?

RealityKit – How to add motion to a loaded ModelEntity from USDZ file?

我已成功将 USDZ 文件加载到我的场景中。现在我想给 ModelEntity 添加动作。我添加了 PhysicsMotionComponent 但它不起作用。加载模型后,它像往常一样是静态的。没有动静。如何在 RealityKit 中给实体运动?

当我看到组件时,我看到组件已添加。但是实体没有动。我做错了什么?

我的代码:

import SwiftUI
import RealityKit
import ARKit
import Combine

struct ARViewContainer: UIViewRepresentable {
    
    
    func makeUIView(context: Context) -> ARView {
        let arVIew = ARView(frame: .zero)
        context.coordinator.arVIew = arVIew
        arVIew.session.delegate = context.coordinator
        let config = ARWorldTrackingConfiguration()
        arVIew.session.run(config, options: [.resetTracking,.removeExistingAnchors])
        
        
        let anchorEntity = AnchorEntity()
 
        
        loadASingleModel(name:"toy_biplane") { entity in
            if let entity = entity {

             let kinematics: PhysicsBodyComponent = .init(massProperties: .default,
                                                                           material: nil,
                                                                               mode: .kinematic)

                        let motion: PhysicsMotionComponent = .init(linearVelocity: [0.1 ,0, 0],
                                                                  angularVelocity: [3, 3, 3])

                        entity.components.set(kinematics)
                        entity.components.set(motion)
                anchorEntity.addChild(entity)
                //anchorEntity.transform.matrix.columns.3.z = -1.0
                arVIew.scene.anchors.append(anchorEntity)
                print("Model Added: ",entity.name)

            }else{
                print("No entity avaible")
            }
        }

        return arVIew
    }
    

    // MARK: - AsychLoading working
    func loadASingleModel(name:String,completion:@escaping (_ model:ModelEntity?)->Void){
        
        var cancellable:AnyCancellable?
        cancellable = Entity.loadModelAsync(named:name)
                    .sink(receiveCompletion: { handler in
                        if case let .failure(error) = handler {
                            print("Unable to load a model due to error \(error)")
                        }
                        cancellable?.cancel()
                        completion(nil)

                    }, receiveValue: { [self] (model: ModelEntity?) in
                        if let model = model  {
                            cancellable?.cancel()
                            print("Congrats! Model is successfully loaded!")
                            completion(model)
                        }
                    })
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {
        
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(arViewContainer: self)
    }
    
    class Coordinator:NSObject{
        var parent:ARViewContainer
        var arVIew:ARView?
        init(arViewContainer:ARViewContainer){
            parent = arViewContainer
        }
    }
}

extension ARViewContainer.Coordinator:ARSessionDelegate{
    
    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        
    }
    
    
    
}

添加到您的代码中 .generateCollisionShapes(recursive:) 每个参与者(实体)的实例方法,它不仅可以创建碰撞的形状,还可以让您模拟物理。

import SwiftUI
import RealityKit

struct ARViewContainer: UIViewRepresentable {
    
    let boxx = ModelEntity(mesh: .generateBox(size: 0.5))
    let ball = ModelEntity(mesh: .generateSphere(radius: 0.25))
    let anchor = AnchorEntity()
    
    func makeUIView(context: Context) -> ARView {
        let arView = ARView(frame: .zero)
        // BALL
        ball.physicsBody = .init()
        ball.physicsMotion = .init()
        ball.physicsMotion?.linearVelocity = [10,0,0]
        ball.position.x = -3
        ball.generateCollisionShapes(recursive: true)
        anchor.addChild(ball)
        // BOX
        boxx.physicsBody = .init()
        boxx.physicsMotion = .init()
        boxx.physicsMotion?.linearVelocity = [0,2,0]
        boxx.generateCollisionShapes(recursive: true)
        anchor.addChild(boxx)
        // Anchor
        anchor.position.z = -3
        arView.scene.addAnchor(anchor)
        return arView
    }
    func updateUIView(_ uiView: ARView, context: Context) { }
}

...

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

有关详细信息,请阅读 THIS post。