我在Scene Kit上制作了一个太空射击游戏,我希望小船在与它们接触时爆炸,我不希望它们发生碰撞,我只是想知道它们何时相互接触。
问题是当船与小行星相交时,我不知道如何实施碰撞检测。例如,我希望Xcode在实际上彼此联系时记录“COLLIDED”。
我已经为这两个对象添加了categoryBitMask
和collisionBitMask
。那么,我怎么能实现这个目标呢?顺便说一句,我在Swift上做的一切。
答案 0 :(得分:2)
SceneKit没有为动态物体提供分离接触检测和碰撞分辨率的选项。 (如果你的一个身体是一个运动体,它不会解决碰撞,但它也不会通过物理学移动。)File a feature request?
然而,听起来您的用例与碰撞解决方案兼容 - 因为小行星爆炸,您不需要关心碰撞对小行星的影响(只需将其从场景中移除并更换它与爆炸VFX,较小的小行星,空间slu ,,等等)。如果船只是为了在碰撞中幸存并且你不希望它受到碰撞的影响,只需设置船和小行星的相对质量,以便小行星不会产生显着的动量。
要在发生碰撞时执行操作,您需要在contact delegate上设置scene's physics world。在作为联系代表的任何类中,实现didBeginContact
方法以在发生冲突时得到通知。
在该方法中,您需要查看联系人的nodeA
和nodeB
,以了解哪些类别的人体相撞(哪个是哪个)。一旦你知道,例如,nodeA
是一艘船而nodeB
是一颗小行星(反之亦然),你可以杀死小行星,更新你的分数等。
答案 1 :(得分:0)
我用更简单的答案来解决这个问题。
在您希望事物通过的节点上,将物理质量设置为一个非常小的数字:
ship.physicsBody.mass = 0.00000000000001;
答案 2 :(得分:-2)
最后我想出了如何解决这个问题。
首先,我为两个物体,宇宙飞船和小行星添加了categoryBitMask
和collisionBitMask
。
ship.physicsBody?.categoryBitMask = 2
asteroid.physicsBody?.categoryBitMask = 4
ship.physicsBody?.collisionBitMask = 4
ball.physicsBody?.collisionBitMask = 2
然后我给了他们两个dynamicBody()
。
ship.physicsBody = SCNPhysicsBody.dynamicBody()
asteroid.physicsBody = SCNPhysicsBody.dynamicBody()
然后我添加了一个NSTimer
来帮助我进行接触检测,每0.1秒更新一次以查看是否有联系。
override func viewDidLoad()
{
NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "checkContact", userInfo: nil, repeats: true)
}
func checkContact()
{
if (self.scene.physicsWorld.contactTestBetweenBody(ship.physicsBody, andBody: asteroid.physicsBody, options: nil) != nil)
{
println("CONTACT!")
}
}
我没有将SCNPhysicsContactDelegate
添加到我的视图中,但最好添加它以确保没有语法问题或警告。
那就是它!
注意:向我们的3D对象添加dynamicBody()
或staticBody()
非常重要,否则它将无法获得联系。在我们将3D dynamicBody()
或staticBody()
添加到我们的场景中之前,将它们添加到我们的3D对象中非常重要。
希望这有助于某人!