0
votes

I'm currently building a game that is implementing collision detection in Scenekit, something I haven't dealt with before.

The game consists of a ship flying through a tunnel, the end goal being that when the ship hits the tunnel it will bounce off.

I have my ship set up using the following:

    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"
    }

And my tunnels are set up this way:

    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, y: 0, 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

Please note that this second tunnel is a custom geometry octagon built up of triangles by specifying the vertices.

At the moment, the game reads as if the tunnels and ship are continuously colliding and it creates a very laggy, bounce-around type aspect to the game. I want it so collisions are only detected when the nodes touch and when they do, the ship will bounce off of the tunnel instead of going through it.

What am I doing wrong and how can I solve this?

Thanks to everyone who took the time to read this.

2
Have you tried running on a physical device? I know there are some issues with physics bodies not working properly in the simulator. But those are around physics bodies not being created properly. It couldn't hurt to try it out.DPrice
Unfortunately, I have, it doesn't make much of a difference.LittleRocketMan
Does this answer your question? SceneKit – Concave collision boxmnuages
Yes, that was very helpful mnuages, thank you.LittleRocketMan

2 Answers

1
votes

Big thanks to the above/below contributors. After using their resources/suggestions and doing a little investigative work myself, I have been able to resolve most of the issues I had.

For anyone new to SCNPhysics who may come across this post, here are a few things I have learned:

  1. Hollow nodes, such as SCNTubes, create solid physics bodies. Both the SCNTube and the custom geometry from my code were creating impassable bodies for my ship.

  2. 'sceneView.debugOptions = SCNDebugOptions.showPhysicsShapes' is incredibly helpful.

  3. Moving a nodes presentation is different than moving the actual location of the node and the physics body will not follow a nodes presentation movement.

0
votes

I could not find any posts about whether or not the inside of an SCNTube can be an area where collisions will not be reported. That would be the question to answer, so first I'd make sure that your shipNode is far enough away and not too big (like turn on physics debug mode) and visually inspect that under idea circumstances it's not touching. If it still reports a collision, I'd make absolutely sure that bit masks are set correctly as that is not one of the easier concepts (for me it wasn't). If that doesn't work and now I'm spitballing... maybe a set of concave walls that form the tubes could work. Past that, I think it comes down to rolling your own pipeline and doing the math yourself.