Reputation: 847
Hi I am trying to remove all nodes from my Scenekit scene but I cannot for the life of me figure out a way.
It seems logical to me that there must be a function for doing this automatically but I cannot find it.
In context, I am trying to remove all nodes so I can reset my scene, which will happen reasonably often. Perhaps there is another way of doing this and I would be fine with that, I'm not stuck with having to remove all nodes.
Thanks!
Upvotes: 20
Views: 20281
Reputation: 1470
For some reason, every single answer on the topic I could find features SCNNode.enumerateChildNodes
method, but using it has a significant downside — it is asynchronous. Meaning you could not be notified when all of node's children had been removed.
Fortunately, there is much more robust approach which takes advantage of childNodes(passingTest:) method. It basically allows you to retrieve all nodes that satisfy a condition, synchronously.
So removal of all child nodes could be achieved in two steps:
// baseNode: SCNNode is defined somewhere in your code
// 1. retrieve all child nodes
let allChildNodes = baseNode.childNodes { _, _ in true }
// 2. remove nodes from their parent
for childNode in allChildNodes {
childNode.removeFromParentNode()
}
Note that we could use the first param of the block for more advanced filtering — say selecting nodes by their name, contents etc.
Upvotes: 2
Reputation:
Modifying a collection while looping through it is not good practice; here's an alternative:
while let n = node.childNodes.first { n.removeFromParentNode() }
Upvotes: 2
Reputation: 129
Here is a solution in Objective-C (Yes it still exists!)
while (self.sceneView.scene.rootNode.childNodes.count) {
NSArray<SCNNode *> *nodes = self.sceneView.scene.rootNode.childNodes;
[nodes[0] removeFromParentNode];
}
Upvotes: 0
Reputation: 2467
For me worked like below:
sceneView.scene.rootNode.enumerateChildNodes { (node, stop) in
node.removeFromParentNode() }
Upvotes: 16
Reputation: 466
Try this (assuming you are using Swift):
rootNode.enumerateChildNodes { (node, stop) in
node.removeFromParentNode()
}
Works for me.
Upvotes: 41
Reputation: 93
the simplest way I found to remove all nodes from a scene is:
self.removeAllChildren()
This worked well for me in XCode version 7.2
Upvotes: -1
Reputation: 1443
Where you need to remove all of your nodes, call this (if your scene isn't self
, change it):
for (SCNNode *node in [self children]) {
[node removeFromParent]
}
Additionally, if you need to remove each node except for some, call this (say, we don't want to remove 3 nodes, and they're named a
, b
, and c
)
for (SCNNode *node in [self children]) {
if (![node.name isEqualToString:@"a"] && ![node.name isEqualToString:@"b"] && ![node.name isEqualToString:@"c"]) {
[node removeFromParent]
}
}
Hope this helps!
Upvotes: 3
Reputation: 13462
you can either create a new scene or call -[SCNNode removeFromParentNode]
on every child node of the scene's rootNode
Upvotes: 3