所以我正在学习如何检查Swift中的bitmask冲突,并且我对是否将两个主体设置为彼此的联系位掩码感到困惑。
我的困惑来自文档中的以下内容:
当两个物理实体重叠时,可能会发生接触。 SceneKit 将身体的接触面罩与另一个身体的类别面具进行比较 执行按位AND运算。如果结果是非零值, SceneKit创建一个描述联系人的SCNPhysicsContact对象 并将消息发送到场景的contactDelegate对象 物理世界。
根据我的理解,碰撞不需要是互惠的 - 换句话说,一个人可以与另一个碰撞而另一个人不动。如果我错了,请纠正我。但是,当涉及到联系人测试时,如果A
将其类别掩码设置为1
并将位掩码设置为2
,并且B
将其类别掩码设置为{{ 1}}及其接触位掩码设置为2
,然后4
和A
会发生冲突作为联系人吗?如果B
现在将其联系人位掩码设置为B
怎么办?两次碰撞会注册吗?
答案 0 :(得分:2)
让我尝试用实际游戏代码中的示例解释所有这些位掩码。这个游戏有以下物体:球,球场,地面,球棒,边界,击球树桩,保龄球树桩,这将有物理相互作用。
很抱歉代码在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
时,您将处理物理代理中的联系人通知,如下所示:
- (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");
}
...
}
总的来说,您只需对对象进行分类,然后设置碰撞遮罩,这只是对象的类别遮罩的按位OR运算,可以与碰撞相对应,并可选择处理彼此的物体接触,设置接触测试位掩码。
但是当涉及到接触测试时,如果A的类别掩码设置为1并且将位掩码设置为2,则
我不确定您是否打算将接触位掩码明确设置为上面的2;联系人掩码应该是与联系人的类别掩码的按位OR运算,并且您希望得到通知。
我认为文档有点令人困惑,希望上面的解释能够清除你的怀疑。