1

I have successfully loaded an USDZ file to my scene. Now I want to add motion the ModelEntity. I have added PhysicsMotionComponent but it is not working. After Loading model it is static as usual. No movement. How to give an entity motion in RealityKit?

When I see the components I see that components are added. But The entity in not moving. What am I doing wrong?

My codes:

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) {
        
    }
    
    
    
}
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
Tanvirgeek
  • 540
  • 1
  • 9
  • 17
  • @AndyJazz Thanks for reply but, I did exactly the same, Only difference is I am loading USDZ model asynchronously and I am using SwiftUI. But my code is not working even though the entity is active and the physicsBody and physicsMotion component is set, I can see them in the console. Why my code is not giving any motion to the entity? – Tanvirgeek Jan 29 '22 at 04:32

1 Answers1

1

Add to your code .generateCollisionShapes(recursive:) instance method for every participant (entity) that not only creates collision's shapes but also allows you to simulate physics.

enter image description here

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)
    }
}

For more details, read THIS post.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220