Apple Engine

Apple, iPhone, iOS, その周辺のことについて

iOS で SceneKit を試す(Swift 3) その70 - PhysicsBody にある3つのビットマスク

PhysicsBody には SCNNode のビットマスクとは別に、
以下のビットマスクが存在している。

  • Category mask
  • Collision mask
  • Contact mask

 

Physics Inspector (Command + Option + 6) でも、
同様のパラメーターがある

f:id:x67x6fx74x6f:20170816151853p:plain

 

Category mask

PhysicsBody の Category mask となり、AND演算の結果が 0 以外であれば同じカテゴリーに所属することとなる。

 

Collision mask

衝突判定となる Collision mask。

CategoryBitmask で同じカテゴリーに所属していて、互いの CollisionBitmask が AND演算の結果が 0 以外であれば、衝突判定が行われる。

そのため、CategoryBitmask と CollisionBitmask の要件が合わないと、Dynamic の PhysicsBody は障害物から突き抜けてしまう。

 

Category mask と Collision mask の使用例

f:id:x67x6fx74x6f:20170816151736g:plain

 

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)

 

今回はここまで。