Невозможно повторно использовать узел эмиттера с другим родителем в iOS9

Я пытаюсь объединить свои узлы эмиттера частиц. Я повторно использую их, когда они необходимы, удаляя их из их старого родительского узла и добавляя их в качестве дочернего элемента SKSpriteNode в новом месте. Я оставляю положение узла эмиттера равным 0,0, поэтому эмиттер должен появиться в центре своего нового родительского узла спрайта.

Эмиттеры отображаются правильно при первом добавлении в качестве дочернего элемента к узлу спрайта, но просто не отображаются при последующих попытках. Все это отлично работало в iOS8 и не работает только в iOS9 (похоже, много ошибок с эмиттерами частиц в iOS9?)

Вот базовый пример моего кода, когда мне нужно разместить эффект частиц:

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

newLocationSpriteNode.addChild(emitter)

emitter.resetSimulation()

Это отлично работало в iOS8 — я мог повторно использовать свои эмиттерные узлы в новых местах. В iOS9 узлы появляются только при первом запуске этого кода и больше никогда не появляются после этого. Есть ли у вас какое-либо представление о том, как я могу обойти эту проблему? Спасибо!


person Stephen    schedule 13.10.2015    source источник
comment
может быть ошибка, которая была в 8, была исправлена ​​в 9, вы правильно сбрасываете излучатель частиц? после этого эмиттер назначается родителю? При сбросе ios 9 теперь останавливает излучатель, и вам нужно заставить его снова запуститься? Просто некоторые вещи, чтобы рассмотреть   -  person Knight0fDragon    schedule 13.10.2015
comment
Привет Рыцарь - спасибо за мысли. Итак, я проверил это с бесконечным эмиттером и без сброса и с той же проблемой. На самом деле оказывается, что вы даже не можете удалить излучатель частиц из узла, а затем снова добавить его в тот же узел. Как только вы удаляете излучатель частиц как дочерний элемент узла, кажется, что вы больше никогда не сможете его использовать.   -  person Stephen    schedule 13.10.2015
comment
вы получаете ошибку, или просто ничего не показывает?   -  person Knight0fDragon    schedule 13.10.2015
comment
Эмиттер работает, когда он впервые добавлен в дерево узлов. Затем, когда я удаляю его и снова добавляю, ничего не отображается. Нет ошибки.   -  person Stephen    schedule 13.10.2015


Ответы (1)


Я столкнулся с точно такой же проблемой, как вы описали. Излучатели не были видны при повторном подключении во второй раз. Хотя на ios8 все работало нормально. После нескольких часов экспериментов с различными настройками я почти сдался. Однако я нашел решение, которое работает сейчас. Во-первых, у меня есть пул SKEmitterNodes, которые я повторно использую во время игры. Этот метод берет эмиттер из пула (массива) и добавляет его в игровой слой (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)
      }
  }

Таким образом, «я» здесь является фактическим узлом, к которому я прикрепляю эмиттер. Когда узел находится за пределами экрана, я очищаю эмиттеры (и другие объекты):

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

У меня еще не было времени вдаваться в подробности, но комментарии «Важно» должны дать вам некоторые подсказки. Я попытаюсь протестировать подход, используя действие для удаления из родителя (через x секунд), но, поскольку я делаю боковую прокрутку, я могу пока обойтись очисткой, когда эмиттеры находятся за пределами экрана.

Надеюсь это поможет..

person Tomas    schedule 27.10.2015
comment
Таким образом, установка целевого узла на новый родительский узел перед добавлением в качестве дочернего, кажется, помогает? Я верю в это - targetNode определенно является одной из самых глючных вещей, с которыми я сталкивался в SpriteKit. Пометка как ответ из-за отсутствия лучшего решения. Хорошая находка! Я переписал свой пул эмиттеров, чтобы просто добавить все в мой мировой узел и изменить положение по мере необходимости некоторое время назад, но я рад, что есть исправление. - person Stephen; 28.10.2015
comment
Да, похоже, а также установка нуля перед возвратом в пул. Выглядит действительно странно. Рад слышать, что вам также удалось найти обходной путь. - person Tomas; 29.10.2015