4

SceneKit 物理世界で衝突しない (互いに跳ね返らない) 2 つのオブジェクト間の接触を検出するための (パフォーマンスに関して) 最良の方法を探しています。

SpriteKit には物理ボディ用の acontactTestBitMaskと aがあり、 collisionBitMaskSceneKit には後者しかないことがわかりました。そのため、SceneKit でオブジェクトが接触したときに通知を受け取る別の好ましい方法が必要です。contactTestBetweenBody:andBody:options:オブジェクトごとに各フレームを呼び出す のは、最善の方法ではないと思いますか?

更新 iOS 9.0 で、ApplecontactTestBitMaskSCNPhysicsBody. したがって、この質問はすぐに時代遅れになります。

4

3 に答える 3

12

この質問は、完全なチュートリアルに値します。つまり、各物理体には、categoryBitMask と collisionBitMask があります。

categoryBitMask 本体を表すビットです。

collisionBitMask これは、どのボディが衝突するかを表すビットです。

デフォルトでは (physicsBody が割り当てられている場合)、特別な動作をする kinematicBody を除いて、すべてのボディが衝突します。オブジェクトは衝突しません。ただし、混乱しないでください。手動で移動すると (指でドラッグするなど)、他のオブジェクトと衝突する可能性があります。

処理する方法!!!

静的か動的かにかかわらず、ボディを割り当てます。そこにカテゴリと衝突マスクを割り当てます。マスクが一致すると、衝突します。一例としていかがでしょうか!

これらの体は互いに衝突します

bodyA.physicsBody.categoryBitMask = 4;
bodyB.physicsBody.categoryBitMask = 8;

bodyA.physicsBody.collisionBitMask = 8;
bodyB.physicsBody.collisionBitMask = 4;

これらは衝突しません

bodyA.physicsBody.categoryBitMask = 4;
bodyB.physicsBody.categoryBitMask = 8;

bodyA.physicsBody.collisionBitMask = 0;
bodyB.physicsBody.collisionBitMask = 0;

2 のべき乗でカテゴリを使用していることに気付きました。これは、contactDelegate がビットごとの AND を使用して比較するためです。わからない場合はビット単位で読んでください。それは本当に役に立ちます。

これらの物体は物理学なしで衝突します

例: 幽霊の中を駆け抜けるヒーローがいて、どちらも影響を受けずにそれが起こったことを知りたいとします。互いに跳ね合うなど。

bodyA.physicsBody.categoryBitMask = 4;
bodyB.physicsBody.categoryBitMask = 8;

bodyA.physicsBody.collisionBitMask = 0;
bodyB.physicsBody.collisionBitMask = 0;

したがって、次のコードは、bodyA (ヒーロー) が bodyB (ゴースト) を介して実行されるように設計されています。

bodyB.physicsField.categoryBitMask = 4

上記がphysicsField.catagoryBitMaskであることに注意してください。bodyA と一致するように 4 が割り当てられます。

let collisionField = SCNPhysicsField.customFieldWithEvaluationBlock(){ 
    (_, _, _, _, _) in 
    WHAT U WANT TO DO ON CONTACT
}

bodyB.physicsField = collisionField

残念ながら、physicsField はジオメトリの形状ではありません。デフォルトは、physicsField プロパティ usesEllipsoidalExtent を「true/yes」に設定した場合、境界ボックスまたは球/楕円形の形状です。

効果の範囲は、physicsFields の halfExtent プロパティを使用して変更できます...

bodyB.physicsField.halfExtent = SCNVector3Make(.5, .5, .5)

上記は、ボックスのフィールドを (2, 2, 2) のサイズから (2.5, 2.5, 2.5) に拡張します。

編集: それでも衝突する場合は、bodyB から物理ボディを削除してみてください (これにより、ノードからすべての物理シミュレーションが削除されます)。カテゴリと衝突ビットマスクが適切に割り当てられている限り、問題にはならないと思います。

これは私が見つけることができる最良の方法です。すべてのコーディングは、Apple ドキュメントのサポートを受けて、私の頭からのものであるため、正確ではないかもしれませんが、これが役立つことを願っています!

于 2014-08-02T15:02:27.333 に答える
0

シーンの物理世界が「contactTestBetweenBody: andBody: withOptions...」を呼び出すことができることを忘れないでください...これはうまく機能します。

使用法

[myScene.physicsWorld contactTestBetweenBody:(SCNPhysicsBody *) andBody:(SCNPhysicsBody *) options:(NSDictionary *)];
于 2015-02-09T02:54:15.240 に答える