未检测到两个节点之间的碰撞ARKit

时间:2019-02-06 20:46:23

标签: swift nodes collision arkit skphysicsbody

我创建了两个节点:一个球体和一个盒子:

    var sphere = SCNNode(geometry: SCNSphere(radius: 0.005))
    //I get the box node from scn file
    let boxScene = SCNScene(named: "art.scnassets/world.scn")!
    var boxNode: SCNNode?

我希望两个节点或physicsBody进行交互,所以我为categoryBitMaskcontactTestBitMask创建了一个类别:

struct CollisionCategory: OptionSet {
    let rawValue: Int
    static let box = CollisionCategory(rawValue: 1)
    static let sphere = CollisionCategory(rawValue: 2)
} 

在这里,我将box节点设置为物理物体:

self.boxScene.rootNode.enumerateChildNodes { (node, _) in
    if node.name == "box" {
        boxNode = node
        let boxBodyShape = SCNPhysicsShape(geometry: SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0.1), options: nil)
        let physicsBody = SCNPhysicsBody(type: .static, shape: boxBodyShape)
        boxNode!.physicsBody = physicsBody
        boxNode!.physicsBody?.categoryBitMask = CollisionCategory.box.rawValue
        boxNode!.physicsBody?.contactTestBitMask = CollisionCategory.sphere.rawValue
        boxNode!.physicsBody?.collisionBitMask = boxNode!.physicsBody!.contactTestBitMask
    }
}

在这里,我在render函数中设置了sphere节点,您可以在视图中四处移动

func setUpSphere() {
         let sphereBodySphere = SCNPhysicsShape(geometry: SCNSphere(radius: 0.005))
         let physicsBody = SCNPhysicsBody(type: .kinematic, shape: sphereBodySphere)
         sphere.physicsBody = physicsBody
         sphere.physicsBody?.categoryBitMask = CollisionCategory.sphere.rawValue
         sphere.physicsBody?.contactTestBitMask = CollisionCategory.box.rawValue
         sphere.geometry?.firstMaterial?.diffuse.contents = UIColor.blue
         sphere.physicsBody?.collisionBitMask = sphere.physicsBody!.contactTestBitMask
         previousPoint = currentPosition 
}

///It Adds a sphere and changes his position
func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {
    guard let pointOfView = sceneView.pointOfView else { return }
    let mat = pointOfView.transform
    let dir = SCNVector3(-1 * mat.m31, -1 * mat.m32, -1 * mat.m33)
    let currentPosition = pointOfView.position + (dir * 0.185)

    if buttonPressed {
        if let previousPoint = previousPoint {
            sphere.position = currentPosition
            sceneView.scene.rootNode.addChildNode(sphere)
        }
     }
}

我将协议SCNPhysicsContactDelegate添加到了ViewController, 然后在ViewDidLoad()中设置:

override func viewDidLoad() {
    super.viewDidLoad()
    sceneView.delegate = self
    sceneView.scene.physicsWorld.contactDelegate = self
    ///I correctly see the shapes of the sphere and the box physics            bodies using
    sceneView.debugOptions = .showPhysicsShapes
    createBox()
    setUpSphere()
    sceneView.scene = boxScene
    sceneView.scene.physicsWorld.contactDelegate = self
}

然后我添加了该功能:

func physicsWorld(_ world: SCNPhysicsWorld, didEnd contact: SCNPhysicsContact) {
        print("Collision!")
}

enter image description here

这就是发生的事情。

当两个节点碰撞时,什么也没有发生,所以我不知道两个物体是否在接触。问题可能是关于.kinematic,.static还是关于函数render()? 我一步一步地遵循了有关ARKit中冲突的不同教程:Tutorial 1Tutorial 2。 我不知道为什么它不能按预期工作。 我的代码有问题吗?

下载文件代码链接: https://ufile.io/20sla

1 个答案:

答案 0 :(得分:1)

每次渲染场景时,

willRenderScene每秒被称为上城60次。由于您每次都在重新创建物理身体时,可能会弄乱物理引擎来确定碰撞。

尝试更改代码,以仅在设置过程中创建一次物理实体。