2

Apple demoed this code in their WWDC 2014 Session 608 video on best practices for SpriteKit.

AppDelegate.m

+ (instancetype)unarchiveFromFile:(NSString *)file {
    /* Retrieve scene file path from the application bundle */
    NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:@"sks"];
    /* Unarchive the file to an SKScene object */
    NSData *data = [NSData dataWithContentsOfFile:nodePath
                                      options:NSDataReadingMappedIfSafe
                                        error:nil];
    NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    [arch setClass:self forClassName:@"SKScene"];
    SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
    [arch finishDecoding];

    return scene;
}

I understand the gist of what it's doing, but what I'm confused about is how to utilize this code in for any other .sks file. I tried calling the unarchiveFromFile method from my GameScene.m class, but to no avail. I read the post here on this topic, but it did not clarify things.

EDIT As per what was suggested by Okapi, I tried the following in a new OS X SceneKit project in the GameScene.m class:

#import "GameScene.h"

@implementation GameScene

-(void)didMoveToView:(SKView *)view {
    SKNode *nodeInScene2 = [self childNodeWithName:@"object1"];
    for (SKNode *blah in [SKScene unarchiveFromFile:@"Scene2"].children) {
        [nodeInScene2 addChild:blah];
    }
}

-(void)update:(CFTimeInterval)currentTime {
    /* Called before each frame is rendered */
}

@end

I have 2 .sks files. The first is called GameScene.sks and that has a sprite in there called "object1". I would like to add children stored in "Scene2.sks". The loop in the didMoveToView method gives me an error. What am I doing wrong? This is what Apple did in their WWDC 608 video, but perhaps I'm missing something since I can't find their project online.

Community
  • 1
  • 1
02fentym
  • 1,762
  • 2
  • 16
  • 29
  • use it like the init method in your view controller `let scene = [GameScene unarchiveFromFile: "your sks filename here"]` –  Dec 17 '14 at 06:58
  • I tried that, it doesn't even show an option for that method. By the way, I'm using objective C not Swift. I tried it in my GameScene class. I tried including the AppDelegate.h header, but nothing seems to work. – 02fentym Dec 17 '14 at 15:53
  • this method should be in your GameScene class files –  Dec 17 '14 at 16:01
  • So, you're saying that I should take the unarchiveFromFile method from the AppDelegate and paste it into GameScene.m? I just tried that, but I must be doing something wrong :/ Is that what you meant though? – 02fentym Dec 17 '14 at 18:57

2 Answers2

1

+unarchiveFromFile: is defined as a category on SKScene in GameViewController.m. You would need to copy that code if you want to use it somewhere else.

@implementation SKScene (Unarchive)

+ (instancetype)unarchiveFromFile:(NSString *)file {
    /* Retrieve scene file path from the application bundle */
    NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:@"sks"];
    /* Unarchive the file to an SKScene object */
    NSData *data = [NSData dataWithContentsOfFile:nodePath
                                          options:NSDataReadingMappedIfSafe
                                            error:nil];
    NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    [arch setClass:self forClassName:@"SKScene"];
    SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
    [arch finishDecoding];

    return scene;
}

@end
Jonny
  • 15,955
  • 18
  • 111
  • 232
0

This one hung me up for a while too. I ended up declaring unarchiveFromFile in every subclass that needed it, then calling it when I wanted to transition scenes. Something like this...

if (contactQuery == (playerCategory | proceedCategory)) {
    SKScene *levelTwo = [LevelTwo unarchiveFromFile:@"LevelTwo"];
    [self.view presentScene:levelTwo transition:[SKTransition doorsCloseHorizontalWithDuration:0.5]];
}

Full sample code can be downloaded here.

Jul3ia
  • 1
  • 2