1
votes

I'm writing a helper method to display a summary of all of the physics interactions (collisions and contacts) in an SpriteKit app on iOS.

I have a simple scene, with a boundary (from self.physicsBody = SKPhysicsBody(edgeLoopFromRect: frame)) and 3 simple shapes (2 squares and a circle) wich are added to the scene via addChild()

In my helper function, I want to search all nodes and if they have a physicsBody, print their category, collision and contactTest bit masks.

If I code the following:

enumerateChildNodesWithNeme("*") { node, _ in {
   print("Node: \(node.name)")
}

then I only get the 3 shapes listed:

Node: Optional("shape_blueSquare")
Node: Optional("shape_redCircle")
Node: Optional("shape_purpleSquare")

My scene's physicsBody is not returned. But if I use:

enumerateChildNodesWithNeme("..") { node, _ in {
   print("Node: \(node.name)")
}

then I get:

Node: Optional("shape_edge") 

If I use:

enumerateChildNodesWithNeme("..//") { node, _ in {
   print("Node: \(node.name)")
}

I get nothing, whereas I thought this would move up the node tree to the scene and then recursively return all children. The search argument "//*" also returns just the 3 children.

All the time, the node count displayed by skView.showNodecount = true is 4.

So my question is: Is there a search argument for enumerateChildNodesWithName that will return all the nodes in a scene (including the scene itself) or have I misunderstood the relationship between the scene and it's children, in that a single search cannot search both? It may be the latter, as print("\(parent.children)") returns nil, when I was expecting to see self or some variation of such.

1
If this is the way that it works, and my code will find all physics bodies other that the scene's physics body, then that's fine - I can just handle that separately. I just want to make sure that I'm not potentially missing anything else.Steve Ives
Printing something like print("\(parent.children)") will always end up with nil. I assume that here, implicit self is a GameScene or something like that. You are getting nil, because (according to the docs), the scene is a root node, so it can't have a parent. For example, you can't remove the scene from its parent (the self.parent property is always nil, when self is a current scene) thus something like self.removeFromParent() has no effect.Whirlwind
@Whirlwind - that makes sense - thanks.Steve Ives
You are welcome. Have you tried the code I've posted as an answer ? Does it work for you ?Whirlwind
I did and it did - just marked up your answer - thanks.Steve Ives

1 Answers

2
votes

This worked for me:

enumerateChildNodesWithName("//.") { (node, _) -> Void in
     print("Node: \(node.name)")
}

About // :

When placed at the start of the search string, this specifies that the search should begin at the root node and be performed recursively across the entire node tree.

About . :

Refers to the current node.

Also this might work for you as well (if you want to find all physics bodies within a given rectangle):

self.physicsWorld.enumerateBodiesInRect(frame) { (body, _) -> Void in
    print(body.node?.name)
}