This question shows how to find all children of a SKNode that belong to a certain class, but what if we want all descendants (e.g., grandchildren) that belong to a certain class?
Is there a native way to do this in SpriteKit, or is the only option to create a recursive form of the solution from the aforementioned question?
The SKNode documentation highlights a search function that lets you find descendants with a certain name, but is there a way to filter descendants by class and not be name? We don't want to assign names to nodes if avoidable.
We're using Swift 3.
Just add this extension to your project
import SpriteKit
extension SKNode {
func allDescendants<Element: SKNode>(byType type: Element.Type) -> [Element] {
let currentLevel:[Element] = children.flatMap { $0 as? Element }
let moreLevels:[Element] = children.reduce([Element]()) { $0 + $1.allDescendants(byType: type) }
return currentLevel + moreLevels
}
}
Now you can fetch all the descendants of an SKNode
having a specific type (e.g. SKSpriteNode
) writing
let descendants = node.allDescendants(byType: SKSpriteNode.self)
class Enemy: SKSpriteNode { }
let root = SKNode()
let a = Enemy()
let b = SKNode()
let c = SKNode()
let d = Enemy()
root.addChild(a)
root.addChild(b)
a.addChild(c)
a.addChild(d)
let enemies: [Enemy] = root.allDescendants(byType: Enemy.self)
print(enemies.count) // 2
What we did was pass a block to the SKNode function that finds nodes by name, and used *
as the search term to avoid assigning a name to desired nodes.
var descendants = [CustomClass]()
nodeToSearch.enumerateChildNodes(withName: ".//*") { node, stop in
if node is CustomClass {
descendants.append(node as! CustomClass)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With