2016-10-05 24 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) 

}