我无法检测 AR/SCNKit 中的碰撞。我发现了这个:如何设置 SceneKit 碰撞检测,虽然有帮助,但我的代码仍然无法正常工作。
主要目标是检测两个场景节点何时接触,一个是球,另一个是充当 scnplane 的 scnbox。
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
}
常量.swift
enum CategoryMask: UInt32 {
case ball = 0b01 // 1
case plane = 0b11 // 2
}
我期待physicsWorld
在飞机和球相撞时被叫到,但它没有发生。非常感谢任何见解。