5

我有一个带有动态物理体的立方体和一个带有运动物理体的平面。当我将一个立方体放在平面上方时,它会落到平面上并且预计会反弹。

问题是:当立方体很小或很轻时,它只是通过平面。例如,立方体有 0.1*0.1*0.1 工作正常,但 0.05*0.05*0.05 很烂。在这种情况下,我仍然会收到身体接触通知。

这是我创建几何的代码:

//cube
//when dimension is 0.1 everything is fine
float dimension = 0.05;
SCNBox *cube = [SCNBox boxWithWidth:dimension height:dimension length:dimension chamferRadius:0];
cube.materials = @[material];
SCNNode *node = [SCNNode nodeWithGeometry:cube];
node.physicsBody = [SCNPhysicsBody bodyWithType:SCNPhysicsBodyTypeDynamic shape:nil];
node.physicsBody.mass = 1;
node.physicsBody.categoryBitMask = phsicBodyCategoryCube;
node.physicsBody.collisionBitMask = phsicBodyCategoryPlane;
node.physicsBody.contactTestBitMask = phsicBodyCategoryPlane;

//plane
self.planeGeometry = [SCNBox boxWithWidth:100 height:0.01 length:100 chamferRadius:0
plane.physicsBody = [SCNPhysicsBody bodyWithType:SCNPhysicsBodyTypeKinematic
                    shape: [SCNPhysicsShape shapeWithGeometry:self.planeGeometry options:nil]];
plane.physicsBody.categoryBitMask = phsicBodyCategoryPlane;
plane.physicsBody.collisionBitMask = phsicBodyCategoryCube;
plane.physicsBody.contactTestBitMask = phsicBodyCategoryCube;
4

3 回答 3

1

最后我发现这都是关于 SceneKit 的物理模拟的。如果立方体落得太快,它会在物理模拟步骤中与平面产生很大的穿透。在这种情况下,sceneKit 只是让它穿过平面而不是碰撞。当我将立方体的速度更改为一个小值时,它与平面相撞。

我的解决方案是在发生大的过度穿透时给立方体一个向上的速度,这是下降速度的 30%。诀窍是调整立方体的速度,直到发生碰撞。

于 2017-07-14T03:05:22.730 回答
1

我很惊讶你会发生碰撞。请参阅SCNPhysicsBodyType 文档——运动学类型适用于您移动的物体(通过设置它们的位置等)以引起碰撞,但它们本身不受与它们碰撞的其他物体的影响。

如果将地板的类型设置为static,您可能会看到更好的结果。静态物体不会移动(由于物理相互作用,或者通过您设置其位置),因此物理引擎可以更准确地检查其他物体是否与它碰撞。


编辑:其他要调查的事情:

  • 为您的地板使用 aSCNPlane而不是 a SCNBox。(请注意,如果有帮助,您可以创建形状与其可见几何形状不同的物理体。)我不确定 SceneKit,但对于许多物理引擎来说更容易检查自从最后一帧?” 而不是“这个框架上的这个有限区域内有一些物体吗?”
  • 为您的移动物体启用精确的碰撞检测。
于 2017-07-07T03:13:19.383 回答
1

Works only for spherical physics shapes

For this issue SCNPhysicsBody has special attribute: continuousCollisionDetectionThreshold

For example, in a game involving projectiles and targets, a small projectile may pass through a target if it moves farther than the target's thickness within one time step. By setting the projectile's continuousCollisionDetectionThreshold to match its diameter, you ensure that SceneKit always detects collisions between the projectile and other objects.

于 2019-03-03T07:48:53.463 回答