4

我正在寻找最好的方法(性能方面)来检测在 SceneKit 物理世界中不碰撞(不相互反弹)的两个对象之间的接触。

我看到 SpriteKit 有 acontactTestBitMask和 acollisionBitMask用于物理体,而 SceneKit 只有后者。因此,当对象在 SceneKit 中有联系时,必须有另一种首选方式来获得通知。我想为每个对象调用 contactTestBetweenBody:andBody:options:每个帧不是最好的方法吗?

更新 在 iOS 9.0 中,Apple 添加contactTestBitMaskSCNPhysicsBody. 所以这个问题很快就会过时。

4

3 回答 3

12

这个问题值得一个完整的教程。总之,每个物理体都有一个categoryBitMask和collisionBitMask。

categoryBitMask 这是代表​​主体的位。

collisionBitMask 这是表示哪些物体与其发生碰撞的位。

默认情况下(当分配一个物理体时)所有的物体都会发生碰撞,除了运动学体,它的作用是特殊的。物体不会与它发生碰撞。但不要混淆,手动移动(例如用手指拖动)时,它可能会与其他对象发生碰撞。

怎么处理!!!

分配你的身体,无论是静态的还是动态的。在那里分配类别和碰撞掩码。如果面罩匹配,它们就会发生碰撞。举个例子怎么样!

这些物体相互碰撞

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;

注意到我使用了二次幂的类别。这是因为contactDelegate 使用按位AND 进行比较。如果您不明白,请按位阅读。这真的会有所帮助。

这些物体在没有物理的情况下碰撞

例子:你有一个英雄穿过一个鬼魂,你想知道它是在没有任何一个被影响的情况下发生的。比如互相反弹。

bodyA.physicsBody.categoryBitMask = 4;
bodyB.physicsBody.categoryBitMask = 8;

bodyA.physicsBody.collisionBitMask = 0;
bodyB.physicsBody.collisionBitMask = 0;

所以下面的代码被设计成bodyA(你的英雄)贯穿bodyB(ghost)。

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 中删除物理体(这将从节点中删除所有物理模拟)。只要正确分配了类别和碰撞位掩码,我认为这不会成为问题。

这是我能找到的最好的方法。在 Apple 文档的支持下,所有编码都出自我的脑海,因此可能并不完全正确,但我希望这会有所帮助!

于 2014-08-02T15:02:27.333 回答
2

我发现最好的方法是将质量设置在一个运动体上,使另一个运动体可以通过它。

sensorBox.physicsBody.mass = 0.00000000001;// 超小质量使其成为“传感器”

于 2014-10-28T01:19:12.027 回答
0

不要忘记你的场景的物理世界可以调用“contactTestBetweenBody:andBody:withOptions...这很好用。

用法

[myScene.physicsWorld contactTestBetweenBody:(SCNPhysicsBody *) andBody:(SCNPhysicsBody *) options:(NSDictionary *)];
于 2015-02-09T02:54:15.240 回答