iOS で SceneKit を試す(Swift 3) その70 - PhysicsBody にある3つのビットマスク
PhysicsBody には SCNNode のビットマスクとは別に、
以下のビットマスクが存在している。
- Category mask
- Collision mask
- Contact mask
Physics Inspector (Command + Option + 6) でも、
同様のパラメーターがある
Category mask
PhysicsBody の Category mask となり、AND演算の結果が 0 以外であれば同じカテゴリーに所属することとなる。
Collision mask
衝突判定となる Collision mask。
CategoryBitmask で同じカテゴリーに所属していて、互いの CollisionBitmask が AND演算の結果が 0 以外であれば、衝突判定が行われる。
そのため、CategoryBitmask と CollisionBitmask の要件が合わないと、Dynamic の PhysicsBody は障害物から突き抜けてしまう。
Category mask と Collision mask の使用例
球
X 値 | -1.5 (奥) | 0 (中央) | 1.5 (手前) |
---|---|---|---|
Category mask | 2 | 1 | 1 |
Collision mask | -1 | 1 | -1 |
ピンクの板
3つとも Static のデフォルト値
- Category mask 2
- Collision mask -3
床(SCNFloor)
- Category mask 1
- Collision mask -3
今までの Bitmask と同様マイナスはすべて許容する。
奥の球は Category mask、中央の球は Collision mask の演算で弾かれるため板を通過する。
さらに、奥の球は Category mask が床との演算でも弾かれるため、床からも通過してしまう。
Contact mask
他の PhysicsBody が接触した際に使用する Contact mask でデフォルト値は 0。
値が 0 以外のノード同士がぶつかり合うと、 SCNPhysicsContactDelegate に SCNPhysicsContact オブジェクトがメッセージとして送られる。
(仕様上、片方が 0 の場合スルーされるはずだが、SCNPhysicsContact が送られる場合があり謎)
Category mask や Collision mask のように衝突処理自体に影響を与えない。
コード
コードでの設定方法。Dynamic での初期値。
let ballNode = SCNNode(geometry: SCNSphere()) ballNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil) ballNode.physicsBody?.categoryBitMask = 1 ballNode.physicsBody?.collisionBitMask = -1 ballNode.physicsBody?.contactTestBitMask = 0 scene.rootNode.addChildNode(ballNode)
今回はここまで。