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
geometry
or its differentfirstMaterials
contents tonil
it 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 = .kinematic
so 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
physicsBody
different collision bitmasks to something that shouldn't cause a collision, but still no luck.I tried to run
physicsBody.resetTransform()
for both theroomNode
and 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
wallNode
was if I recreated the wholeroomNode.physicsBody
like 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!