为什么SCNNode之间会发生连续冲突?

问题描述 投票:0回答:2

我正在尝试在SCNNode之间设置冲突检测,但是遇到问题。

第一步,我已经设置了我的班级以扩展SCNPhysicsContactDelegate

class ViewController: SCNPhysicsContactDelegate
.
.
.
self.arSceneView.scene.physicsWorld.contactDelegate = self

我有两种类型的SCNNodes:carcoins。对于两者,我都设置了碰撞类别:

// Collisions
struct CollisionCategory: OptionSet {
    let rawValue: Int

    static let CoinsCategory = CollisionCategory(rawValue: 4)
    static let CarCategory = CollisionCategory(rawValue : 8)
}

两者都分配了一个PhysicalBody,我为每个分配了类别交互元素的种类

汽车

// 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

Coin

// 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")
...
...
...

以下图像给出了场景情况的概念:

image

我不知道设置中有什么错误或缺少什么。

[当汽车靠近某些立方体(硬币)时,它们会影响它,因此发生“碰撞”,但是,我不明白...

image

谢谢!

swift collision-detection scenekit arkit
2个回答
0
投票

您可以尝试这样的事情:

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))!)
            }
        }
    }

0
投票

确定,我通过添加此控件来解决:

func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
    if(contact.penetrationDistance >= 0.08 && contact.nodeB.name!.contains("Coin")) {
        contact.nodeB.removeFromParentNode()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.