У меня проблемы с обнаружением коллизий в AR / SCNKit.Я нашел это: Как настроить обнаружение коллизий SceneKit , хотя это полезно, но мой код по-прежнему не работает.
Основная цель - обнаружить, когда два узла сцены соприкасаются, одинball, другой - это scnbox, выполняющий роль scnplane.
ViewController.swift
class ViewController: UIViewController, ARSCNViewDelegate, SCNPhysicsContactDelegate{
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene()
sceneView.scene = scene
sceneView.scene.physicsWorld.contactDelegate = self
}
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
let width = CGFloat(planeAnchor.extent.x)
let length = CGFloat(planeAnchor.extent.z)
let planeHeight = CGFloat(0.01)
let plane = SCNBox(width: width, height:planeHeight, length:length, chamferRadius: 0)
plane.materials.first?.diffuse.contents = UIColor.orange
let planeNode = SCNNode(geometry: plane)
let x = CGFloat(planeAnchor.center.x)
let y = CGFloat(planeAnchor.center.y)
let z = CGFloat(planeAnchor.center.z)
planeNode.position = SCNVector3(x,y,z)
planeNode.physicsBody = SCNPhysicsBody(type:.kinematic, shape: SCNPhysicsShape(geometry:plane, options:nil))
planeNode.physicsBody?.categoryBitMask = Int(CategoryMask.plane.rawValue)
planeNode.physicsBody?.collisionBitMask = Int(CategoryMask.ball.rawValue) | Int(CategoryMask.plane.rawValue)
}
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
print("-> didBeginContact")
}
func physicsWorld(_ world: SCNPhysicsWorld, didUpdate contact: SCNPhysicsContact) {
print("-> didUpdateContact")
}
func physicsWorld(_ world: SCNPhysicsWorld, didEnd contact: SCNPhysicsContact) {
print("-> didEndContact")
}
Ball.swift
class Ball {
init(x: Float, y: Float, z:Float){
let sphereNode = SCNNode()
let sphere = SCNSphere(radius: 0.05)
sphereNode.addChildNode(SCNNode(geometry: sphere))
sphereNode.position = SCNVector3(x, y, z)
self.node = sphereNode
self.node.physicsBody = SCNPhysicsBody(type: .dynamic, shape: SCNPhysicsShape(geometry:sphere, options:nil))
self.node.physicsBody?.categoryBitMask = Int(CategoryMask.ball.rawValue)
self.node.physicsBody?.collisionBitMask = Int(CategoryMask.ball.rawValue) | Int(CategoryMask.plane.rawValue)
self.node.physicsBody?.friction = 1
self.node.physicsBody?.mass = 2.0
}
Constants.swift
enum CategoryMask: UInt32 {
case ball = 0b01 // 1
case plane = 0b11 // 2
}
Я ожидаю, что physicsWorld
позвонят, когда самолет и мяч столкнутся, но этого не происходит.Любое понимание очень ценится.