为什么我会在 SCNNode 之间发生连续碰撞?
Why I get a continuous collision between SCNNodes?
我正在尝试设置 SCNNode 之间的碰撞检测,但我遇到了问题。
作为第一步,我设置了 class 以扩展 SCNPhysicsContactDelegate
:
class ViewController: SCNPhysicsContactDelegate
.
.
.
self.arSceneView.scene.physicsWorld.contactDelegate = self
我有 2 种 SCNNode:汽车 和 硬币。对于两者,我都设置了碰撞类别:
// Collisions
struct CollisionCategory: OptionSet {
let rawValue: Int
static let CoinsCategory = CollisionCategory(rawValue: 4)
static let CarCategory = CollisionCategory(rawValue : 8)
}
两者都分配了一个 physicsBody,我为它们分配了 类别 和 一种交互元素。
汽车
// Create physics shape
let boxBodyShape = SCNPhysicsShape(node: carNode, options: nil)
// Create physics body
let boxBody = SCNPhysicsBody(type: .kinematic, shape: boxBodyShape)
// Assign physics body
carNode.physicsBody = boxBody
// Setup category collisions properties
carNode.physicsBody?.categoryBitMask = CollisionCategory.CarCategory.rawValue
carNode.physicsBody?.contactTestBitMask = CollisionCategory.CoinsCategory.rawValue
carNode.physicsBody?.collisionBitMask = CollisionCategory.CoinsCategory.rawValue
硬币
// Create physics body
let boxBody = SCNPhysicsBody(type: .kinematic, shape: boxBodyShape)
// Assign physics body
coin.physicsBody = boxBody
// Setup category collisions properties
coin.physicsBody?.categoryBitMask = CollisionCategory.CoinsCategory.rawValue
coin.physicsBody?.contactTestBitMask = CollisionCategory.CarCategory.rawValue
coin.physicsBody?.collisionBitMask = CollisionCategory.CarCategory.rawValue
最后一步,我实现了函数 physicsWorld(:didBegan:)
来管理冲突:
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
print("A: \(contact.nodeA.name) - B: \(contact.nodeB.name)")
print("A: \(contact.nodeA.physicsBody!.categoryBitMask) - B: \(contact.nodeB.physicsBody!.categoryBitMask)")
}
所有这一切都在工作,但没有达到预期。即使没有碰撞,我也会在场景中连续碰撞汽车和硬币。控制台输出不断给我一个碰撞:
...
...
...
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin9")
...
...
...
下图大概了解一下现场情况:
我不明白设置中出了什么问题或遗漏了什么。
似乎当汽车靠近一些立方体(硬币)时,它们会影响它,所以 "collision" 但是,我不明白...
谢谢!
您可以尝试这样的操作:
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact)
{
if(data.gameState == .run)
{
guard let nodeNameA = contact.nodeA.name else { return }
guard let nodeNameB = contact.nodeB.name else { return }
if(nodeNameA.prefix(5) == "Explo" && nodeNameB.prefix(5) == "Missi")
{
gameControl.enemyMissileHit(vIndex: Int(nodeNameB.suffix(4))!)
}
if(nodeNameA.prefix(5) == "Missi" && nodeNameB.prefix(5) == "Explo")
{
gameControl.enemyMissileHit(vIndex: Int(nodeNameA.suffix(4))!)
}
if(nodeNameA.prefix(5) == "Explo" && nodeNameB.prefix(5) == "Hive ")
{
gameControl.enemyHiveHit(vIndex: Int(nodeNameB.suffix(4))!)
}
if(nodeNameA.prefix(5) == "Hive " && nodeNameB.prefix(5) == "Explo")
{
gameControl.enemyHiveHit(vIndex: Int(nodeNameA.suffix(4))!)
}
}
}
好的,我通过添加这个控件解决了:
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
if(contact.penetrationDistance >= 0.08 && contact.nodeB.name!.contains("Coin")) {
contact.nodeB.removeFromParentNode()
}
}
我正在尝试设置 SCNNode 之间的碰撞检测,但我遇到了问题。
作为第一步,我设置了 class 以扩展 SCNPhysicsContactDelegate
:
class ViewController: SCNPhysicsContactDelegate
.
.
.
self.arSceneView.scene.physicsWorld.contactDelegate = self
我有 2 种 SCNNode:汽车 和 硬币。对于两者,我都设置了碰撞类别:
// Collisions
struct CollisionCategory: OptionSet {
let rawValue: Int
static let CoinsCategory = CollisionCategory(rawValue: 4)
static let CarCategory = CollisionCategory(rawValue : 8)
}
两者都分配了一个 physicsBody,我为它们分配了 类别 和 一种交互元素。
汽车
// Create physics shape
let boxBodyShape = SCNPhysicsShape(node: carNode, options: nil)
// Create physics body
let boxBody = SCNPhysicsBody(type: .kinematic, shape: boxBodyShape)
// Assign physics body
carNode.physicsBody = boxBody
// Setup category collisions properties
carNode.physicsBody?.categoryBitMask = CollisionCategory.CarCategory.rawValue
carNode.physicsBody?.contactTestBitMask = CollisionCategory.CoinsCategory.rawValue
carNode.physicsBody?.collisionBitMask = CollisionCategory.CoinsCategory.rawValue
硬币
// Create physics body
let boxBody = SCNPhysicsBody(type: .kinematic, shape: boxBodyShape)
// Assign physics body
coin.physicsBody = boxBody
// Setup category collisions properties
coin.physicsBody?.categoryBitMask = CollisionCategory.CoinsCategory.rawValue
coin.physicsBody?.contactTestBitMask = CollisionCategory.CarCategory.rawValue
coin.physicsBody?.collisionBitMask = CollisionCategory.CarCategory.rawValue
最后一步,我实现了函数 physicsWorld(:didBegan:)
来管理冲突:
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
print("A: \(contact.nodeA.name) - B: \(contact.nodeB.name)")
print("A: \(contact.nodeA.physicsBody!.categoryBitMask) - B: \(contact.nodeB.physicsBody!.categoryBitMask)")
}
所有这一切都在工作,但没有达到预期。即使没有碰撞,我也会在场景中连续碰撞汽车和硬币。控制台输出不断给我一个碰撞:
...
...
...
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin8")
A: 8 - B: 4
Penetration distance: false
A: Optional("Car") - B: Optional("Coin9")
...
...
...
下图大概了解一下现场情况:
我不明白设置中出了什么问题或遗漏了什么。
似乎当汽车靠近一些立方体(硬币)时,它们会影响它,所以 "collision" 但是,我不明白...
谢谢!
您可以尝试这样的操作:
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact)
{
if(data.gameState == .run)
{
guard let nodeNameA = contact.nodeA.name else { return }
guard let nodeNameB = contact.nodeB.name else { return }
if(nodeNameA.prefix(5) == "Explo" && nodeNameB.prefix(5) == "Missi")
{
gameControl.enemyMissileHit(vIndex: Int(nodeNameB.suffix(4))!)
}
if(nodeNameA.prefix(5) == "Missi" && nodeNameB.prefix(5) == "Explo")
{
gameControl.enemyMissileHit(vIndex: Int(nodeNameA.suffix(4))!)
}
if(nodeNameA.prefix(5) == "Explo" && nodeNameB.prefix(5) == "Hive ")
{
gameControl.enemyHiveHit(vIndex: Int(nodeNameB.suffix(4))!)
}
if(nodeNameA.prefix(5) == "Hive " && nodeNameB.prefix(5) == "Explo")
{
gameControl.enemyHiveHit(vIndex: Int(nodeNameA.suffix(4))!)
}
}
}
好的,我通过添加这个控件解决了:
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
if(contact.penetrationDistance >= 0.08 && contact.nodeB.name!.contains("Coin")) {
contact.nodeB.removeFromParentNode()
}
}