Couldn't find a solution or an answer online ...
I'm building an AR game using SceneKit.
I have a roomNode which has several wallNodes as children.
The whole roomNode is set to detect collisions.
It all works perfectly fine. Except ...
In the game I allow the user to tap a wall to remove it, at which point I would allow the user to walk through the missing wall without a collision being detected. At least that's what I want to happen ... After identifying the node with a hitTest, I just run:
node?.removeFromParentNode()
The problem is that I see the wall correctly being removed, but collisions continue to occur at the location where the wallNode used to be and now it's just empty space.
When I turn on debugging to show physics shapes and feature points like so:
sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin, SCNDebugOptions.showPhysicsShapes]
after removing the wall, I still see the outline of that removed wall as if it's still there. Like a ghost of the wall still exists and it's still part of the higher level roomNode which still detects collisions.
Here are different things that I tried to solve this issue:
I saw in some other threads that after setting the node's
geometryor its differentfirstMaterialscontents tonilit would free some memory that was kept so I also tried doing that, but it didn't change anything.I also tried setting the node itself to
nil, but that didn't help either.I tried changing that node's
physicsBody.type = .kinematicso that even if a ghost remains in my scene, at least collisions wouldn't move the node, but that didn't work either.I also tried changing the node's
physicsBodydifferent collision bitmasks to something that shouldn't cause a collision, but still no luck.I tried to run
physicsBody.resetTransform()for both theroomNodeand for the node that was removed and that also did nothing.The only thing that actually removed the ghost completely and allowed me to walk through the removed
wallNodewas if I recreated the wholeroomNode.physicsBodylike that:roomNode?.physicsBody = SCNPhysicsBody(type: .dynamic, shape: SCNPhysicsShape(node: roomNode!, options: nil))
So that did the trick. But then, if my roomNode was previously moved due to collisions or if I moved the roomNode myself in code (using a pivot to reorient the room for the game's purposes), after recreating the whole physicsBody, the whole roomNode would redraw in a different location.
I can now try to figure out how to compensate for any node movement, but that can become very tricky if at all possible.
But there should be a correct way to remove some tapped node so that it would get completely removed from the scene without leaving any ghosts.
Don't know if this has any relevance, but the roomNode is defined globally as a property of my ViewController.
The different wallNodes on the other hand, are each created elsewhere locally and then added as child nodes.
If anyone knows how I could resolve this or if you have any clue I could try, please let me know. Thanks!