Scenekit检测不存在的碰撞-有关Scenekit碰撞检测的一般建议

问题描述

我目前正在开发一款在Scenekit中实现碰撞检测的游戏,这是我以前从未处理过的事情。

游戏由一艘飞过隧道的船组成,最终目标是当船撞到隧道时会反弹。

我使用以下方法设置了飞船:

    func setupShipNodes() {
        shipNode = scene.rootNode.childNode(withName: "ship",recursively: true)!
        shipNode.name = "shipNode"
        let shipPhysicsShape = SCNPhysicsShape(node: shipNode)
        shipNode.physicsBody = SCNPhysicsBody(type: .dynamic,shape: shipPhysicsShape)
        shipNode.physicsBody?.contactTestBitMask = shipNode.physicsBody!.collisionBitMask
        
        shipMesh = scene.rootNode.childNode(withName: "shipMesh",recursively: true)
        shipMesh.name = "shipMesh"
    }

我的隧道是这样建立的:

    func setupTunnel() {
        tunnelShape = SCNTube(innerRadius: 5,outerRadius: 5,height: 100)
        tunnelNode = SCNNode(geometry: tunnelShape)
        tunnelNode.geometry?.firstMaterial?.diffuse.contents = UIColor.orange
        tunnelNode.position = SCNVector3(x: 0,y: 0,z: 0)
        tunnelNode.eulerAngles = SCNVector3(x: 1.5708,z: 0)
        
        let physicsShape = SCNPhysicsShape(geometry: tunnelShape)
        tunnelNode.physicsBody = SCNPhysicsBody(type: .static,shape: physicsShape)
        tunnelNode.physicsBody?.contactTestBitMask = tunnelNode.physicsBody!.collisionBitMask
        tunnelNode.name = "tunnelNode"
        
        scene.rootNode.addChildNode(tunnelNode)
        let material = SCNMaterial()
        material.isDoubleSided = true
        material.diffuse.contents = UIColor.red
        addedTunnelNode.geometry?.firstMaterial = material
        addedTunnelNode.geometry?.firstMaterial? = material
        
        let physicsShape = SCNPhysicsShape(geometry: geometry)
        addedTunnelNode.physicsBody = SCNPhysicsBody(type: .static,shape: physicsShape)
        addedTunnelNode.physicsBody?.contactTestBitMask = addedTunnelNode.physicsBody!.collisionBitMask

请注意,第二个隧道是通过指定顶点由三角形组成的自定义几何八边形。

此刻,游戏读取的内容似乎是隧道和飞船在不断碰撞,并且为游戏创造了一个非常滞后的反弹型外观。我想要这样,以便仅在节点接触时才检测到碰撞,而当节点接触时,船会从隧道弹开,而不是通过隧道。

我在做什么错,我该如何解决

感谢所有花时间阅读本文的人。

解决方法

非常感谢上面/下面的贡献者。在使用他们的资源/建议并自己进行了一些调查工作之后,我已经能够解决我遇到的大多数问题。

对于SCNPhysics的新手来说,我可能学到了以下几点:

  1. 空心节点(例如SCNTube)创建实体物理实体。我的代码中的SCNTube和自定义几何都为我的船创建了无法逾越的物体。

  2. 'sceneView.debugOptions = SCNDebugOptions.showPhysicsShapes'非常有用。

  3. 移动节点表示与移动节点的实际位置不同,物理实体将不会跟随节点表示的移动。

,

我找不到有关SCNTube内部是否可以报告冲突的区域的任何文章。那将是要回答的问题,因此首先我要确保您的shipNode足够远且不太大(例如打开物理调试模式),并在思想环境下目视检查它是否没有碰到。如果仍然报告冲突,我将绝对确保正确设置位掩码,因为这不是更简单的概念之一(对我而言不是)。如果那不起作用,现在我正在吐口水……也许形成管子的一组凹壁可以起作用。除此之外,我认为这取决于滚动自己的管道并自己做数学。