Home > front end >  How can I let the plane collide with an object in RealityKit
How can I let the plane collide with an object in RealityKit

Time:01-21

I have a ball and a plane (floor) in realityKit. The ball falls and has to collide on the plane. But the ball is falling through the plane. When the ball hits the plane i want a print statement "OCCURED" but this is also not happening.

My code:

struct ARViewContainer: UIViewRepresentable {
    
    let arView = ARView(frame: .zero)
    
    func makeUIView(context: Context) -> ARView {

        var subscriptions: [Cancellable] = []
        
        let anchor = AnchorEntity()
    
        //generate a plane
        let planeModel = ModelEntity(mesh: .generatePlane(width: 2.0, 
                                    depth: 2.0))
        as (Entity & HasCollision)
       
        planeModel.position = [0,-10,-1.5]
        planeModel.generateCollisionShapes(recursive: true)
        
        //generate a ball
        let ballModel = ModelEntity(mesh: .generateSphere(radius: 0.4))
                                 as (Entity & HasCollision & HasPhysicsBody)
        ballModel.generateCollisionShapes(recursive: true)
        ballModel.position = [0,0, -1.5]
        
        ballModel.physicsBody = .init()
        ballModel.physicsBody?.mode = .dynamic
        
        let sub = arView.scene.subscribe(to: CollisionEvents.Began.self,
                                on: ballModel) { _ in print("OCCURED!") }
        subscriptions.append(sub)
        
        anchor.addChild(ballModel)
        anchor.addChild(planeModel)
        arView.scene.addAnchor(anchor)
        
        return arView
    }
}

CodePudding user response:

Collider and collidee

This code activates physics and prints "occured" N times, thanks to CollisionEvents' subscription:

import SwiftUI
import RealityKit
import Combine

struct ARViewContainer: UIViewRepresentable {
    
    @State var subscriptions: [AnyCancellable] = []
    let arView = ARView(frame: .zero)
    let anchor = AnchorEntity()
    
    func makeUIView(context: Context) -> ARView {

        // PLANE
        let planeModel = ModelEntity(mesh: .generatePlane(width: 2.0,
                                                          depth: 2.0)) 
                                                   as (Entity & HasPhysics)
       
        planeModel.position = [0,-1,-1.5]
        planeModel.generateCollisionShapes(recursive: false)
        planeModel.physicsBody = .init()
        planeModel.physicsBody?.mode = .static
        
        // BALL
        let ballModel = ModelEntity(mesh: .generateSphere(radius: 0.2), 
                               materials: [UnlitMaterial()])
                                                   as (Entity & HasPhysics)

        ballModel.position = [0, 1,-1.5]
        ballModel.generateCollisionShapes(recursive: false)            
        ballModel.physicsBody = .init()
        ballModel.physicsBody?.mode = .dynamic
        
        DispatchQueue.main.async {

            arView.scene.subscribe(to: CollisionEvents.Began.self,
                                   on: ballModel) { _ in
                print("OCCURED!")
                
            }.store(in: &subscriptions)
        }    
        anchor.addChild(ballModel)
        anchor.addChild(planeModel)
        arView.scene.addAnchor(anchor)           
        return arView
    }
    func updateUIView(_ view: ARView, context: Context) { }
}

struct ContentView : View {
    var body: some View {
        ARViewContainer().ignoresSafeArea()
    }
}

enter image description here

  • Related