我有一个带有动态物理体的立方体和一个带有运动物理体的平面。当我在平面上方放置一个立方体时,它将落在平面上并且预期会发生反弹。
问题是:当立方体小或轻时,它只是通过平面。例如,立方体有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;
我很惊讶你发生了碰撞。请参阅SCNPhysicsBodyType docs - 运动类型适用于您移动的物体(通过设置其位置等)以引起碰撞,但这些物体本身不会受到与其碰撞的其他物体的影响。
如果你将地板的类型设置为static,你可能会看到更好的结果。静态物体不会移动(无论是物理相互作用的结果,还是通过设置其位置),因此物理引擎可以更准确地检查与其发生碰撞的其他物体。
编辑:要研究的其他事项:
SCNPlane
而不是SCNBox
作为你的地板。 (请注意,你可以创建形状与其可见几何形状不同的物理体,如果有帮助的话。)我不确定SceneKit,但很多物理引擎更容易检查“有一些物体通过这个无限边界,因为最后一帧?“比“这个有限区域内的某个物体在这个框架上?”最后我发现这都是关于SceneKit的物理模拟。如果立方体下降太快,它会在平面上进行大的穿透。在物理模拟步骤中。在这种情况下,sceneKit只是让它通过飞机而不是碰撞。当我将立方体的速度更改为较小的值时它与平面相撞。
我的解决方案是在发生大的过度穿透时给立方体一个向上的速度,这是下降速度的30%。诀窍是调整立方体的速度直到碰撞发生。
仅适用于球形物理形状
对于这个问题,SCNPhysicsBody
有特殊属性:continuousCollisionDetectionThreshold
例如,在涉及射弹和目标的游戏中,如果小射弹在一个时间步长内移动的距离超过目标的厚度,则小射弹可以穿过目标。通过设置射弹的continuousCollisionDetectionThreshold以匹配其直径,您可以确保SceneKit始终检测射弹与其他物体之间的碰撞。