2016-10-05 45 views
2

我有一個具有複雜幾何圖形的太空船對象,並且由於SceneKit的物理不適用於複雜的物體,因此我採用了一種解決方法:我使用了一些基本形狀和立方體如此模擬整個飛船的身體。在攪拌機我創建一組對象近似於飛船的形狀:碰撞沒有正確檢測到多個幾何形狀

enter image description here

然後,當予加載予刪除這些對象的場景,但使用它們的幾何形狀來構造SCNPhysicsShape用作飛船的物理體:

// 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對象應包含我在攪拌機文件創建的形狀。但是當我測試這個程序時,宇宙飛船就像一個空的物體,並且沒有發現碰撞。

PS:我的目標只是檢測碰撞。我不希望物理引擎模擬物理。

+0

我懷疑其他人曾試圖自己在做什麼。很少有人使用SceneKit。似乎更少用於遊戲。其他人不太可能導入物理體。我認爲您需要爲兩到三名在此閒逛的SceneKit員工提供一個示例打包項目。他們可能是唯一可以幫助解決這個問題的人。 – Confused

+0

如果你看看那些回答了很多SceneKit問題的傢伙,我想你可以弄清楚他們是誰。而且你有這麼多的代表,你可以跟他們聊聊聊天室,或者其他一些直接交流的方式。 – Confused

+0

@Confused你有什麼建議用於遊戲? –

回答

2

你想爲你的船使用凹形。下面的例子。爲了使用凹面,您的身體必須是靜態的或運動的。運動是理想的動畫物體。

無需:

body.collisionBitMask = 0 

接觸位掩碼是所有你需要的唯一接觸。

下面的代碼應該適用於您正在查找的內容。這是快速的3代碼fyi。

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

沒有看到你的位掩碼,我無法告訴你,如果被正確地處理這些。你應該是這樣的:你想聯繫

spaceship.physicsBody.categoryBitMask = 1 << 1 

任何你的飛船應該有:

otherObject.physicsBody.contactTestBitMask = 1 << 1 

這將只註冊了「otherObject」的接觸到了「飛船」,而不是「太空船」到「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) 

}