所以我正在学习如何在 Swift 中检查位掩码冲突,并且我对是否将两个实体设置为具有彼此的接触位掩码感到困惑。
我的困惑来自文档中的以下内容:
When two physics bodies overlap, a contact may occur. SceneKit compares the body’s contact mask to the other body’s category mask by performing a bitwise AND operation. If the result is a nonzero value, SceneKit creates an SCNPhysicsContact object describing the contact and sends messages to the contactDelegate object of the scene’s physics world.
据我了解,碰撞不需要是相互的 - 换句话说,一个可以与另一个碰撞,而另一个则保持不动。如果我错了,请纠正我。但在接触测试时,如果A
的类别掩码设置为1
,接触位掩码设置为2
,并且B
的类别掩码设置为 2
,其联系人位掩码设置为 4
,然后将 A
和 B
冲突注册为联系人?如果 B
现在将其联系人位掩码设置为 1
会怎样?会记录两次碰撞吗?
最佳答案
让我尝试用实际游戏代码的示例来解释所有这些位掩码。该游戏具有以下对象:球、球场、地面、球棒、边界、击球树桩、保龄球树桩,它们将具有物理相互作用。
抱歉,代码是用 ObjC 编写的,但转换为 Swift 很简单。
第 1 步:设置类别位掩码,指定每个对象的类型
typedef NS_OPTIONS(NSUInteger, CollisionCategory) {
CollisionCategoryBall = 1 << 1,
CollisionCategoryPitch = 1 << 2,
CollisionCategoryGround = 1 << 3,
CollisionCategoryBat = 1 << 4,
CollisionCategoryBoundary = 1 << 5,
CollisionCategoryBattingStumps = 1 << 6,
CollisionCategoryBowlingStumps = 1 << 7,
};
第 2 步:现在我们决定哪些对象彼此发生碰撞。
例如,对于球对象,存在与球场、地面球棒和边界的碰撞。设置如下,按位 OR 运算,假设 ballBody
是 SCNPhysicsBody
:
ballBody.collisionBitMask =
(CollisionCategoryPitch | CollisionCategoryGround | CollisionCategoryBat |
CollisionCategoryBoundary);
第 3 步:(可选),如果您希望在两个物理体相互接触时收到通知。
在这里,您设置 contactTestBitMask。以球为例,我希望在它与球场、地面、球棒、边界接触时收到通知。再次强调,要做到这一点:
ballBody.contactTestBitMask =
(CollisionCategoryPitch | CollisionCategoryGround | CollisionCategoryBat |
CollisionCategoryBoundary);
当您设置contactTestBitMask
时,您将在物理委托(delegate)中处理接触通知,如下所示:
- (void)physicsWorld:(SCNPhysicsWorld*)world
didBeginContact:(SCNPhysicsContact*)contact {
CollisionCategory contactMask = contact.nodeA.physicsBody.categoryBitMask |
contact.nodeB.physicsBody.categoryBitMask;
if ((contactMask == (CollisionCategoryBall | CollisionCategoryPitch)) &&
!self.ballLandedOnPitch) {
NSLog(@" Ball hit the pitch");
}
...
}
因此,总的来说,您只需对对象进行分类,然后设置碰撞掩码,这只是将发生碰撞的对象的类别掩码的按位或运算,并且可以选择处理物体之间的接触,设置接触测试位掩码。
But when it comes to contact testing, if A has its category mask set to 1 and contact bitmask set to 2,
我不确定您是否打算将联系人位掩码显式设置为上面的 2;联系人掩码实际上应该是对象的类别掩码的按位或运算,与该对象有联系人并且您希望收到通知。
我认为这些文档有点令人困惑,希望上述解释能消除您的疑虑。
关于swift - 联系人和类别位掩码 - 只需要设置其中之一还是两者都需要设置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41341729/