Search code examples
swiftsprite-kitskscene

Add SKReferenceNode programmatically


I have long 2d level so I split it into more .sks files. I have "GameScene" where I can join them in Scene editor with drag and drop. It creates SKReferenceNodes. I've done that with success. But I would like to load these parts lazily when it's needed in code (it's said to be good practice). I'm failing on that.

This is particular part of code:

if let nextPart = SKReferenceNode(fileNamed: "Scene2_city2") {
        if self.childNodeWithName("Scene2_city2") == nil {
            self.addChild(nextPart)
        }
    }

"Scene2_city2" is name of .sks file and also name of Scene inside the file.

Running the code I get an error:

*** Terminating app due to uncaught exception 'Cant add body, already exists in a world', reason: 'Cant add body type: representedObject:[ name:'Scene2_city2' frame:{{-0, -0}, {1024, 768}} anchor:{0, 0}], already exists in a world'

This is very strange, because I first check it before I added.

Question: How should I add SKReferenceNode into SKScene programmatically?

EDIT: Here is simple example project on bitbucket. Reference scene is added for tap.


Solution

  • I've found a workaround, it turns out there are no issues when creating a SKReferenceNode using the URL method. For example:

    let path = NSBundle.mainBundle().pathForResource("SpaceShip", ofType: "sks")
    let spaceShip = SKReferenceNode (URL: NSURL (fileURLWithPath: path!))
    addChild(spaceShip)
    

    I did a little digging and it appears in 7.3.1 vs 7.2.1 when creating a SKReferenceNode using fileNamed it now returns an optional. When unwrapped you get the SKScene which will of course throw out errors if you try and add it as a child to an existing scene.

    Added a quick 7.3 test project https://github.com/cocojoe/SKReferenceNodeIssue/tree/workaround

    Notice you referenced my post on the Apple forum. I filled a bug report about a month ago, from past experience these can take a while to be looked at.