我正在寻找最佳方式(性能方面)来检测 SceneKit 物理世界中两个不碰撞(不相互反弹)的物体之间的接触。
我看到 SpriteKit 有一个 contactTestBitMask
和一个用于物理体的 collisionBitMask
而 SceneKit 只有后者。因此,当对象在 SceneKit 中发生接触时,必须有另一种首选方式来获得通知。我想在每个对象的每个帧中调用 contactTestBetweenBody:andBody:options:
不是最好的方法吗?
更新
在 iOS 9.0 中,Apple 已将 contactTestBitMask
添加到 SCNPhysicsBody
。所以这个问题很快就会过时。
最佳答案
这个问题值得一个完整的教程。简而言之,每个物理体都有一个categoryBitMask和collisionBitMask。
类别位掩码 这是代表 body 的位。
碰撞位掩码 这是代表哪些物体与之碰撞的位。
默认情况下(当指定一个 physicsBody 时)所有物体都会发生碰撞,但 kinematicBody 除外,它的行为很特殊。物体不会与之碰撞。但不要混淆,手动移动时(例如用手指拖动)它可能会与其他对象发生碰撞。
如何处理!!!
分配你的 body ,无论是静态的还是动态的。在那里分配类别和碰撞掩码。如果掩码匹配,它们就会发生碰撞。举个例子怎么样!
这些物体相互碰撞
bodyA.physicsBody.categoryBitMask = 4;
bodyB.physicsBody.categoryBitMask = 8;
bodyA.physicsBody.collisionBitMask = 8;
bodyB.physicsBody.collisionBitMask = 4;
它们不会碰撞
bodyA.physicsBody.categoryBitMask = 4;
bodyB.physicsBody.categoryBitMask = 8;
bodyA.physicsBody.collisionBitMask = 0;
bodyB.physicsBody.collisionBitMask = 0;
注意到我使用了 2 的幂的类别。这是因为 contactDelegate 使用按位 AND 进行比较。如果您不明白,请按位阅读。这真的会有帮助。
这些物体在没有物理的情况下发生碰撞
示例:您有一个英雄穿过幽灵,您想知道它发生时没有任何一个受到影响。比如互相弹跳。
bodyA.physicsBody.categoryBitMask = 4;
bodyB.physicsBody.categoryBitMask = 8;
bodyA.physicsBody.collisionBitMask = 0;
bodyB.physicsBody.collisionBitMask = 0;
所以设计了下面的代码,让bodyA(你的英雄)贯穿bodyB(幽灵)。
bodyB.physicsField.categoryBitMask = 4
注意到上面是一个physicsField.catagoryBitMask。它被指定为 4,以便与 bodyA 匹配。
let collisionField = SCNPhysicsField.customFieldWithEvaluationBlock(){
(_, _, _, _, _) in
WHAT U WANT TO DO ON CONTACT
}
bodyB.physicsField = collisionField
不幸的是,physicsField 不是您的几何形状。如果将 physicsField 属性 usesEllipsoidalExtent 设置为“true/yes”,它的默认值是其边界框或球体/椭圆形的形状
效果区域可以使用 physicsFields 的 halfExtent 属性来改变,就像这样......
bodyB.physicsField.halfExtent = SCNVector3Make(.5, .5, .5)
上面的代码会将大小为 (2, 2, 2) 的框的字段扩展为 (2.5, 2.5, 2.5)。
编辑:如果它们仍然发生碰撞,请尝试从 bodyB 中移除 physicsbody(这将从节点中移除所有物理模拟)。只要类别和碰撞位掩码分配正确,我认为这不会成为问题。
这是我能找到的最好的方法。在 Apple 文档的支持下,所有编码都来 self 的头脑,因此可能不完全正确,但我希望这对您有所帮助!
关于ios - SceneKit:如何在没有碰撞的情况下检测接触,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25065933/