0

我无法检测 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在飞机和球相撞时被叫到,但它没有发生。非常感谢任何见解。

4

0 回答 0