17.1 C
New York
Monday, March 31, 2025

Do not perceive iOS RealityKit’s collision detection


I’m attempting to detect collisions between two RealityKit entities, however the outcomes are surprising.

I thus created a minimal instance. Within the iOS app under, 3 entities are arrange:
A board, a set field and a transferring field.
The board and the first field do not transfer, whereas the 2nd field strikes in the direction of the first field.
All 3 entities have a collisionShape.
As a result of Physics simulation just isn’t used, each packing containers have their collision mode set to .set off.
Each packing containers belong to the identical CollisionGroup, and their collision filter is about to this group.

A CollisionManager subscribes to the start of collision occasions. If a collision is detected, the collision is logged.

When the app is began, the 2nd field is transferring in the direction of the first one till each are on the identical place. No collision is logged. I anticipated that the collision between each packing containers can be detected.

If setting of the collision filter of a field is out commented, the next is logged when the app begins (the various RealityKit logs are omitted):

collision started between board and Fastened field
collision started between Fastened field and board
collision started between board and Shifting field
collision started between Shifting field and board

Clearly, collision might be detected, however a collision between each packing containers just isn’t. However why?

Right here is my code:

//
//  CollisionApp.swift
//  Collision
//
//  Created by Reinhard Männer on 31.03.25.
//

import SwiftUI

@predominant
struct CollisionApp: App {
    var physique: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}  

//
//  CollisionManager.swift
//  Collision
//
//  Created by Reinhard Männer on 31.03.25.
//

import Mix
import Basis
import RealityKit

class CollisionManager {
    var movementTimer: Timer?
    non-public var updateVehicleCollisionSubscription: Cancellable?
    
    func startVehicleCollisionTrigger(scene: RealityKit.Scene) {
        updateVehicleCollisionSubscription = scene.subscribe(to: CollisionEvents.Started.self) { occasion in
            let a = occasion.entityA
            let b = occasion.entityB
            print("collision started between (a.identify) and (b.identify)")
        }
    }

    func startMovement(entity: Entity) {
        movementTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
            if entity.place.x > 0 {
                entity.place.x -= 0.02
            } else {
                timer.invalidate()
                self.movementTimer = nil
            }
        }
    }
}

//
//  ContentView.swift
//  Collision
//
//  Created by Reinhard Männer on 31.03.25.
//

import RealityKit
import SwiftUI

struct ContentView: View {
    let collisionManager = CollisionManager()
    let boardHeight: Float = 0.1
    let boxHeight: Float = 0.3
    
    var physique: some View {
        var movingBox: Entity?
        
        RealityView { content material in
            let board = makeBoard()
            content material.add(board)
            
            let box1 = makeBox(identify: "Fastened field")
            board.addChild(box1)
            
            movingBox = makeBox(identify: "Shifting field")
            movingBox?.place.x = 0.8
            board.addChild(movingBox!)
        }
        replace: { content material in
            let scene = content material.entities.first?.scene
            collisionManager.startVehicleCollisionTrigger(scene: scene!)
            collisionManager.startMovement(entity: movingBox!)
        }
    }
    
    func makeBoard() -> ModelEntity {
        let mesh = MeshResource.generateBox(width: 2.0, top: boardHeight, depth: 1.0)
        var materials = UnlitMaterial(); materials.colour.tint = .pink
        let boardEntity = ModelEntity(mesh: mesh, supplies: [material])
        boardEntity.identify = "board"
        boardEntity.generateCollisionShapes(recursive: false)

        boardEntity.rework.translation = [0, 0, -3]
        return boardEntity
    }
    
    func makeBox(identify: String) -> ModelEntity {
        let mesh = MeshResource.generateBox(width: 0.2, top: boxHeight, depth: 0.3)
        var materials = UnlitMaterial(); materials.colour.tint = .inexperienced
        let boxEntity = ModelEntity(mesh: mesh, supplies: [material])
        boxEntity.identify = identify
        
        // To place the field onto the board, transfer it up by half top of the board and half top of the field
        let y_up = boardHeight/2.0 + boxHeight/2.0
        boxEntity.place = SIMD3(0, y_up, 0)
        
        // Enable to detect collisions between packing containers solely and to set off code execution.
        boxEntity.generateCollisionShapes(recursive: false)
        boxEntity.collision!.mode = .set off
        let collisionGroup = CollisionGroup(rawValue: 1 << 0)
        let filter = CollisionFilter(group: collisionGroup, masks: collisionGroup)
        boxEntity.collision!.filter = filter
        
        return boxEntity
    }

}

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles