SceneKit之物理模拟中的碰撞检测

2019-05-15  本文已影响0人  沈枫_ShenF

关于物理体的物理模拟中接触与碰撞检测,SceneKit提供了一个类SCNPhysicsContact和一个协议SCNPhysicsContactDelegate,接下来我们来认识下它们。

SCNPhysicsContactDelegate

在一个场景中,当两个物理体发生了接触和碰撞,通过此协议能接收他们之间接触的详细信息。并提供给我们一些列代理方法来做进一步的处理,SceneKit会在以下三种情况下调用对应的代理方法:

  1. when a contact begins。
optional func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact)
  1. when information about the contact changes
optional func physicsWorld(_ world: SCNPhysicsWorld, didUpdate contact: SCNPhysicsContact)
  1. when the contact ends
optional func physicsWorld(_ world: SCNPhysicsWorld, didEnd contact: SCNPhysicsContact)

SCNPhysicsContact

在一个场景的物理模拟中,该类给出了两个物理体之间接触的详细信息。当接触发生时,SceneKit会自动生成SCNPhysicsContact对象,因此我们不必手动去创建它们。要想收到这些接触信息,需要做如下两步:

  1. 在你自定义的类里,实现SCNPhysicsContactDelegate
       // set SCNPhysicsContactDelegate
       scnScene.physicsWorld.contactDelegate = self
  1. 给场景中的每个物理体,设置categoryBitMask和collisionBitMask属性,来定义哪些交互应该产生接触信息。 每次碰撞时,用自己的Collision mask(碰撞掩码)和别人的Category mask(分类掩码)做按位与运算,运算结果为零则不能碰撞,运算结果不为零则会碰撞.
    同理Contact mask(接触掩码)也是和别人的Category mask(分类掩码)做按位与运算,运算结果为零则不会通知,运算结果不为零则会通知.
//设置各节点的Category mask(分类掩码)
//Ball:          1 (Decimal) = 00000001 (Binary)
//Barrier:    2 (Decimal) = 00000010 (Binary)
//Brick:       4 (Decimal) = 00000100 (Binary)
//Paddle:    8 (Decimal) = 00001000 (Binary)

enum ColliderType: Int {
  case Ball = 0b1
  case Barrier = 0b10
  case Brick = 0b100
  case Paddle = 0b1000
}
//设置小球与哪些类型碰撞时调用代理通知
ballNode.physicsBody?.contactTestBitMask = ColliderType.Barrier.rawValue
|  ColliderType.Brick.rawValue | ColliderType.Paddle.rawValue

SCNPhysicsContact中的属性

上一篇 下一篇

猜你喜欢

热点阅读