3

I'm trying to pool my particle emitter nodes. I re-use them when they are needed by removing them from their old parent node and adding them as a child of a SKSpriteNode at a new location. I leave the emitter node position set to 0,0 so the emitter should appear in the center of its new parent sprite node.

The emitters display correctly the first time they are added as a child to a sprite node, but simply do not show up on subsequent attempts. This all worked great in iOS8 and is only broken in iOS9 (seems like lots of particle emitter bugs in iOS9?)

Here's a basic example of my code when I need to place the particle effect:

if emitter.parent != nil {
    emitter.removeFromParent()
}

newLocationSpriteNode.addChild(emitter)

emitter.resetSimulation()

This worked perfectly in iOS8 - I could re-use my emitter nodes at new locations. In iOS9 the nodes only appear the first time this code runs and never show up again after. Do you have any insight into how I might work around this issue? Thanks!

Stephen
  • 642
  • 1
  • 4
  • 22
  • could be a bug that was in 8 that got fixed in 9, are you resetting the particle emitter correctly? is the emitter being assigned the parent aftewards? On reset does ios 9 now stop the emitter and you need to force it to run again? Just some things to consider – Knight0fDragon Oct 13 '15 at 16:26
  • Hi Knight - thanks for the thoughts. So I tested this with a never-ending emitter and without the reset and the same issue. In fact, it appears you can't even remove a particle emitter from a node and then re-add it to the same node. As soon as you remove a particle emitter as a child of a node it seems like you can never use it again. – Stephen Oct 13 '15 at 18:23
  • do you get an error, or just nothing shows? – Knight0fDragon Oct 13 '15 at 18:25
  • The emitter works when it's first added to the node tree. Then when I remove it and re-add it, nothing shows. No error. – Stephen Oct 13 '15 at 18:35

1 Answers1

2

I experienced the exact same problem as you described. Emitters were not visible when re-attached for the second time. Everything worked fine on ios8 though. After several hours of experimenting with different settings I almost gave up.. However, I found a solution that works now. First of all I have a pool of SKEmitterNodes which I re-use during gameplay. This method grabs an emitter from the pool (array) and adds it to the gameplay-layer (SKNode):

    func createExplosion(position: CGPoint) {

      let emitter = _pool.borrowDirtEmitter()

      emitter.resetSimulation() //Important
      emitter.position = position
      emitter.targetNode = self //Important

      if emitter.parent == nil {
        self.addChild(emitter)
      }
  }

So "self" here is the actual node that I attach the emitter to. When the node is offscreen I clean up emitters (and other objects):

        if let dirtEmitter = childNode as? SKEmitterNode {
            if dirtEmitter.parent != nil {
                dirtEmitter.removeFromParent()
            }
            dirtEmitter.targetNode = nil //Important!
            _pool.returnDirtEmitter(dirtEmitter)
        }

I haven´t had the time to go into more detail yet, but the "Important" comments should give you some pointers. I will try testing out an approach using an action to remove from parent as well (after x seconds), but since I´m making a side scroller I can get away with cleaning up when emitters are offscreen for now.

Hope this helps..

Tomas
  • 46
  • 3
  • So setting the target node to the new parent node before adding as a child seems to do the trick? I believe it - targetNode is definitely one of the more buggy things I've experienced in SpriteKit. Marking as an answer for lack of a better solution. Good find! I rewrote my emitter pool to just add everything to my "world" node and reposition as needed a while back, but I'm glad there's a fix out there. – Stephen Oct 28 '15 at 06:59
  • Yes, seems like it, and also setting to nil before returning to pool. Seems strange really. Glad to hear you managed to find a workaround as well. – Tomas Oct 28 '15 at 22:03