1

I've been updating a SpriteKit/GameplayKit project for Xcode 8 and the new Scene Editor which allows adding Entity-Component information to a scene. I've been to move my entity code into the scene, but I'm having trouble accessing the entity from the corresponding node. As per Apple's documentation:

Any SpriteKit node in the scene to which you’ve attached an entity or components automatically has a GKSKNodeComponent object to manage the relationship between the node and the the GKEntity object it represents.

and

Adding a GKSKNodeComponent object to an entity automatically updates the entity property of the component’s SpriteKit node (an SKNode object) to point to that entity.

The new code I have to load the scene is basically as follows:

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))

Accessing the GKScene object returns an array of properly loaded entities, but if I try to access an entity with GKEntity.entity from a connected node, it returns nil. The node is connected through accessing GKSKNodeComponent.node from an entity in GKScene.

How do I get GKSKNodeComponent and GKScene to automatically update SKNode's entity property as expected?

Duncan Oliver
  • 39
  • 1
  • 9
  • Do you keep `newTowerScene` around, or might it be out of scope / deallocated by the time you're looking for a node's `entity`? That property is weak, and the entities are owned by the `GKScene`, so if you dispose of the scene without otherwise storing its entities list, the entities go away and the weak reference nils out. – rickster Sep 16 '16 at 21:47
  • Thanks, @rickster! I do retain `GKScene` via a property on a `SKScene` subclass, but even if I set a breakpoint right after initializing the `GKScene`, the same behavior is observed. – Duncan Oliver Sep 16 '16 at 22:05

1 Answers1

1

In case anyone else runs into this problem…

I noticed that if I added an entity with an associated node to the GKScene after loading, the node's entity property was properly set. For now, I added a loop that run after loading a 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)
    }

It doesn't seem to work unless the previous GKSKNodeComponent is replaced, either. Hopefully this is just a temporary fix to a bug that will be resolved quickly.

Duncan Oliver
  • 39
  • 1
  • 9