联系人和类别位掩码 - 是否只需要设置一个,或者两者都需要设置?
Contact and category bitmask - does only one, or both, need to be set?
所以我正在学习如何检查 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 步:现在我们决定哪些对象相互碰撞。
比如球对象,有与球场、地棒和边界的碰撞。设置如下,按位或运算,假设 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");
}
...
}
总的来说,你只需对你的对象进行分类,然后设置碰撞掩码,它只是对将要发生碰撞的对象的类别掩码进行按位或操作,并可选择处理物体之间的接触,设置接触测试位掩码。
But when it comes to contact testing, if A has its category mask set to 1 and contact bitmask set to 2,
我不确定你是否打算在上面明确地将接触位掩码设置为2;联系人掩码实际上应该是对象的类别掩码的按位或运算,将有联系人并且您希望收到通知。
我觉得文档有点混乱,希望上面的解释能解开你的疑惑。
所以我正在学习如何检查 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 步:现在我们决定哪些对象相互碰撞。
比如球对象,有与球场、地棒和边界的碰撞。设置如下,按位或运算,假设 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");
}
...
}
总的来说,你只需对你的对象进行分类,然后设置碰撞掩码,它只是对将要发生碰撞的对象的类别掩码进行按位或操作,并可选择处理物体之间的接触,设置接触测试位掩码。
But when it comes to contact testing, if A has its category mask set to 1 and contact bitmask set to 2,
我不确定你是否打算在上面明确地将接触位掩码设置为2;联系人掩码实际上应该是对象的类别掩码的按位或运算,将有联系人并且您希望收到通知。
我觉得文档有点混乱,希望上面的解释能解开你的疑惑。