我正在尝试使用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.contactDelegatesceneView是ARSCNView。
我正确地看到了physicsBody的形状
SCNDebugOptionShowPhysicsShape为什么会发生这种事?
发布于 2017-09-08 11:52:01
您的节点不会相互交互,因为它们属于不同的类别。下面是collsionBitMask如何根据文献资料工作
当两个物理物体相互接触时,可能会发生碰撞。SceneKit通过按位和操作将身体的碰撞掩码与另一个身体的类别掩码进行比较。如果结果是一个非零值,那么物体就会受到碰撞的影响。
contactBitMask和categoryBitMask的工作原理相同。
当SceneKit检查您的physicsBody是否有联系人时,会发生这样的情况:
object1.physicsBody.contactTestBitMask = 4 = 0100b
object2.physicsBody.categoryBitMask = 8 = 1000b
-----
(bitwise AND) 0000b = 0 -> no collision定义类别的最好方法是使用OptionSet,苹果实际上在SCNPhysicsCollisionCategory中为您提供默认类别。
如果您想要两个节点或物理体进行交互,那么它们至少需要共享一个类别的。否则它们就不会相撞。
下面是您的示例应该是什么样的样子:
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
}https://stackoverflow.com/questions/46091056
复制相似问题