首页 文章

在 ARkit 中未检测到 SceneKit 冲突

提问于
浏览
1

我正在尝试使用 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 回答

  • 3

    您的节点不会相互交互,因为它们位于不同的类别中。以下是collsionBitMask如何根据文件工作:

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

    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
     }
    

相关问题