2016-10-05 13 views
2

複雑なジオメトリを持つ宇宙船オブジェクトがあり、SceneKitの物理が複雑なボディでは機能しないため、回避策を採用しました。シリンダーのような基本的な形状を使用していますキューブは宇宙船の体全体をシミュレートします。私は、これらのオブジェクトを削除シーンをロードするときにマルチジオメトリシェイプで衝突が正しく検出されない

enter image description here

、しかしとして使用することをSCNPhysicsShapeを構築するために彼らのジオメトリを使用します。Blenderでは、私は、宇宙船の形状を近似するオブジェクトのセットを作成しました宇宙船の物理ボディ:

// First I retrieve all of these bodies, which I named "Body1" up to 9: 
let bodies = _scene.rootNode.childNodes(passingTest: { (node:SCNNode, stop:UnsafeMutablePointer<ObjCBool>) -> Bool in 
    if let name = node.name 
    { 
     return name.contains("Body") 
    } 
    return false 
}) 

// Then I create an array of SCNPhysicsShape objects, and an array 
// containing the transformation associated to each shape 
var shapes = [SCNPhysicsShape]() 
var transforms = [NSValue]() 
for body in bodies 
{ 
    shapes.append(SCNPhysicsShape(geometry: body.geometry!, options: nil)) 
    transforms.append(NSValue(scnMatrix4:body.transform)) 
    // I remove it from the scene because it shouldn't be visible, as it has 
    // the sole goal is simulating the spaceship's physics 
    body.removeFromParentNode() 
} 

// Finally I create a SCNPhysicsShape that contains all of the shapes 
let shape = SCNPhysicsShape(shapes: shapes, transforms: transforms) 
let body = SCNPhysicsBody(type: .dynamic, shape: shape) 
body.isAffectedByGravity = false 
body.categoryBitMask = SpaceshipCategory 
body.collisionBitMask = 0 
body.contactTestBitMask = RockCategory 
self.spaceship.physicsBody = body 

SCNPhysicsShapeオブジェクトが、私はBlenderのファイルで作成されたすべての図形が含まれている必要があります。しかし、私がプログラムをテストすると、宇宙船は空の体のように振る舞い、衝突は検出されません。

PS:私の目標は、衝突を検出することだけです。私は物理エンジンに物理学をシミュレートさせたくありません。

+0

私は他の誰が何をやっているしようとした疑い。 SceneKitを使う人はほとんどいません。たとえそれがゲームに使用されるようでもあります。物理学のために輸入された身体を持っている人はいないでしょう。私はあなたがここにたどり着いている2人か3人のSceneKitの従業員のために、パッケージされたサンプルプロジェクトを提供する必要があると思います。彼らはおそらくこれを助けることができる唯一の人々です。 – Confused

+0

SceneKitの質問にたくさん答える人を見れば、あなたは彼らが誰であるかを知ることができます。そして、あなたはおそらくそれらとのチャットルームやその他の直接コミュニケーションの手段を始めることができるような膨大な数の担当者を持っています。 – Confused

+0

@Confusedまた、ゲームに使うことをお勧めしますか? –

答えて

2

船に凹形を使用したいとします。以下の例。凹面を使用するには、あなたの体は静的または運動学的でなければなりません。 Kinematicはアニメーションオブジェクトに最適です。

は必要ない:

body.collisionBitMask = 0 

接触ビットマスクは、あなただけの接触のために必要なすべてのです。

下記のコードは、探しているもので動作するはずです。これは迅速な3コードです。

let body = SCNPhysicsBodyType.kinematic 
let shape = SCNPhysicsShape(node: spaceship, options: [SCNPhysicsShape.Option.type: SCNPhysicsShape.ShapeType.concavePolyhedron]) 
spaceship.physicsBody = SCNPhysicsBody(type: body, shape: shape) 

あなたのビットマスクを見なければ、私はあなたが適切にそれらを処理しているかどうか言うことができません。これが唯一の「宇宙船」に「otherObject」の連絡先を登録しません

otherObject.physicsBody.contactTestBitMask = 1 << 1 

spaceship.physicsBody.categoryBitMask = 1 << 1 

あなたの宇宙船が持つべき連絡したい何か:あなたのような何かを持っている必要があります「宇宙船」を「otherObject」に変換します。だから、あなたの物理世界の連絡担当者がそのように扱われていることを確認してください。両方のオブジェクトがお互いを探す必要はありません。それはあまり効率的ではありません。下記のデリゲートの

例:

func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) { 

    var tempOtherObject: SCNNode! 
    var tempSpaceship: SCNNode! 

    // This will assign the tempOtherObject and tempSpaceship to the proper contact nodes 
    if contact.nodeA.node == otherObject { 
     tempOtherObject = contact.nodeA 
     tempSpaceship = contact.nodeB 
    }else{ 
     tempOtherObject = contact.nodeB 
     tempSpaceship = contact.nodeA 
    } 

    print("tempOtherObject = ", tempOtherObject) 
    print("tempSpaceship = ", tempSpaceship) 

} 
関連する問題