SpriteKit: find all descendants of SKNode of a particular class?

This question shows how to find all children of SKNode belonging to a specific class, but what if we want all descendants (such as grandchildren) belonging to a specific class?

Is there a native way to do this in SpriteKit or is this the only way to create a recursive solution form from the above question?

The SKNode documentation highlights a search function that allows you to find descendants with a specific name, but is there a way to filter descendants by class and not be named? We don't want to assign names to nodes if they can be avoided.

We are using Swift 3.

+3


source to share


2 answers


What we did was pass a block to the SKNode function, which finds the nodes by name, and used it *

as a search term to avoid naming the desired nodes.



    var descendants = [CustomClass]()
    nodeToSearch.enumerateChildNodes(withName: ".//*") { node, stop in
        if node is CustomClass {
            descendants.append(node as! CustomClass)
        }
    }

      

+2


source


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 get all descendants of a SKNode

specific type (for example SKSpriteNode

) by writing



let descendants = node.allDescendants(byType: SKSpriteNode.self)

      

Example

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

      

+1


source







All Articles