GKScene и SKNode.entity

Я обновлял проект SpriteKit/GameplayKit для Xcode 8 и нового редактора сцен, который позволяет добавлять в сцену информацию Entity-Component. Я должен был переместить свой код объекта в сцену, но у меня возникли проблемы с доступом к объекту из соответствующего узла. Согласно документации Apple:

Любой узел SpriteKit в сцене, к которому вы присоединили объект или компоненты, автоматически имеет объект GKSKNodeComponent для управления отношениями между узлом и объектом GKEntity, который он представляет.

и

Добавление объекта GKSKNodeComponent к сущности автоматически обновляет свойство сущности узла SpriteKit компонента (объект SKNode), чтобы оно указывало на эту сущность.

Новый код, который мне нужно загрузить, в основном выглядит следующим образом:

guard let newTowerScene = GKScene(fileNamed: "TowerScene"),
    let rootScene = newTowerScene.rootNode as? SKScene 
    else { return }
self.view?.presentScene(rootScene, transition: SKTransition.push(with: .up, duration: 1.75))

Доступ к объекту GKScene возвращает массив правильно загруженных объектов, но если я попытаюсь получить доступ к объекту с GKEntity.entity из подключенного узла, он вернет nil. Узел подключен через доступ к GKSKNodeComponent.node из объекта в GKScene.

Как заставить GKSKNodeComponent и GKScene автоматически обновлять свойство entity SKNode, как и ожидалось?


person Duncan Oliver    schedule 16.09.2016    source источник
comment
Вы держите newTowerScene рядом, или он может быть вне области действия/освобожден к тому времени, когда вы ищете узел entity? Это свойство является слабым, а сущности принадлежат GKScene, поэтому, если вы избавляетесь от сцены, не сохраняя список ее сущностей, сущности исчезают, а слабая ссылка обнуляется.   -  person rickster    schedule 17.09.2016
comment
Спасибо, @rickster! Я сохраняю GKScene через свойство подкласса SKScene, но даже если я устанавливаю точку останова сразу после инициализации GKScene, наблюдается такое же поведение.   -  person Duncan Oliver    schedule 17.09.2016


Ответы (1)


В случае, если кто-то еще столкнется с этой проблемой…

Я заметил, что если я добавлял сущность со связанным узлом в GKScene после загрузки, свойство узла entity устанавливалось правильно. А пока я добавил цикл, который запускается после загрузки GKScene:

for nextEntity in gkScene.entities
    {
        gkScene.removeEntity(nextEntity)
        if let nextNode = nextEntity.component(ofType: GKSKNodeComponent.self)?.node
        {
            nextEntity.addComponent(GKSKNodeComponent(node: nextNode))
        }
        gkScene.addEntity(nextEntity)
    }

Похоже, это не работает, если не заменить предыдущий GKSKNodeComponent. Надеемся, что это всего лишь временное исправление ошибки, которая будет устранена быстро.

person Duncan Oliver    schedule 19.09.2016
comment
Отличный совет! Вы проверили, исправили? Спасибо! - person Sungwook Kim; 08.07.2019