在ARkit中未检测到SceneKit冲突

时间:2017-09-07 08:02:54

标签: swift scenekit arkit

我尝试使用ARkit和SceneKit构建游戏,但在设置了physicsWorld委托和对象的物理主体之后,没有调用委托方法didBeginContact。

这是我的物理主体结构

struct CollisionCategory {
    static let moltenBullet :Int = 4
    static let iceShield :Int = 8
}

这就是我设置物理主体的方式

 let collisionShape = SCNPhysicsShape(node: node, options: nil)
        self.physicsBody = SCNPhysicsBody(type: .dynamic, shape: collisionShape)
        self.physicsBody?.categoryBitMask = self.categoryMask
        self.physicsBody?.contactTestBitMask = self.collisionMask
        self.physicsBody?.collisionBitMask = self.collisionMask

我使用self是因为它是继承自SCNNode的自定义类的物理主体,在构造函数中使用上面的结构设置了collisionMask和categoryMask。

在didBeginContact中,我想打印一些但没有任何反应。 我已经将SCNPhysicsContactDelegate设置为

sceneView.scene.physicsWorld.contactDelegate

sceneView是ARSCNView。

我正确地看到了物理体的形状

SCNDebugOptionShowPhysicsShape

为什么会这样?

1 个答案:

答案 0 :(得分:3)

您的节点之间不会互相交互,因为它们属于不同的类别。 以下是collsionBitMask根据the documentation的工作原理:

  

当两个物理实体相互接触时,可能会发生碰撞。 SceneKit通过执行按位AND运算将 body的碰撞掩码其他正文的类别掩码进行比较。如果结果为非零值,则主体会受到碰撞的影响。

contactBitMaskcategoryBitMask的工作方式相同。

当SceneKit检查你的physicsBody的联系人时,会发生这种情况:

object1.physicsBody.contactTestBitMask = 4 = 0100b
object2.physicsBody.categoryBitMask    = 8 = 1000b
                                             -----
                               (bitwise AND) 0000b = 0 -> no collision

定义类别的最佳方式是使用OptionSet,Apple实际上会在SCNPhysicsCollisionCategory中为您提供默认类别。

如果您想要两个节点或physicsBody进行交互,则需要至少共享一个类别。否则他们不会发生碰撞。

以下是您的示例应该如何:

struct CollisionCategory: OptionSet {
    let rawValue: Int

    static let moltenBullet = CollisionCategory(rawValue: 4)
    static let iceWall = CollisionCategory(rawValue : 8)
}

然后你分配你的类别:

class Bullet: SCNNode {
    ...

    // The physics body-category is a bullet
    self.physicsBody?.categoryBitMask = CollisionCategory.moltenBuller.rawValue
    // This contacts with both other bullets and ice walls!
    self.physicsBody?.contactBitMask = [CollsionCategory.moltenBullet, CollisionCategory.iceWall].rawValue
    self.physicsBody?.collisionBitMask = self.physicsBody!.contactBitMask
 }