Sarreph
Sarreph

Reputation: 2015

Passing variables to SKScene

I'm trying to pass a preloaded array of SKTextures from my SpriteKit scene's UIViewController when into the scene when it is initialised.

However, I cannot seem to customise the initialisation method for SKScene to pass in an array.

This is what I am trying to do:

@interface MyViewController ()

@property (nonatomic, strong) NSArray *texturePack;

@end

<>

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    // Configure the view.
    SKView * skView = (SKView *)self.spriteView;
    if (!skView.scene) {
        skView.showsFPS = YES;
        skView.showsNodeCount = YES;

        // Create and configure the scene.

        // Pass variable?*

        MyScene *scene = [MyScene initWithSize:skView.bounds.size];

        scene.scaleMode = SKSceneScaleModeAspectFill;

        // Present the scene.
        [skView presentScene:scene];          

    }

}

*I am not sure how to pass self.texturePack to the Scene before it is initialised?

If anybody has any advice on how to pass variables to an SKScene as they are initialised, I would be most grateful.

Upvotes: 1

Views: 2108

Answers (2)

Andrew97p
Andrew97p

Reputation: 565

If I were you, I would just create a singleton class that passes has that array as a property, and you just access it from there.

//SharedTextures.h
@interface SharedTextures : NSObject
@property (strong, nonatomic)NSArray *textures;
@end

//sharedTextures.m
+ (instancetype)sharedInstance{

    static dispatch_once_t onceToken;
    static id sharedInst;
    dispatch_once(&onceToken, ^{
    sharedInst = [[self alloc] init];
});
    return sharedInst;
}
- (id)init{
    self.textures = [self loadTextures]
}

Now when anyone wants those textures, you can call:

SharedTextures *shared = [SharedTextures sharedInstance];
SKTexture *texture = shared.textures[//indice of texture];

The benefit to this is you only ever load the textures once, and you don't need to pass them around from scene to scene. Either approach would be valid, but this provides better code encapsulation, because you texture loading code can all go into this one class now, so it is in a central place.

Upvotes: 1

Mick MacCallum
Mick MacCallum

Reputation: 130222

You have to declare the property publicly in your subclass of SKScene.

@interface MyScene : SKScene

@property (nonatomic, strong) NSArray *texturePack;

@end

Then, when you create your scene's instance. Set a value to the newly declared property. Once you do this, you can access the array from within your instance of your scene.

SKView * skView = (SKView *)self.spriteView;
if (!skView.scene) {
    skView.showsFPS = YES;
    skView.showsNodeCount = YES;

    MyScene *scene = [MyScene initWithSize:skView.bounds.size];
    [scene setTexturePack:someArrayReference];

    scene.scaleMode = SKSceneScaleModeAspectFill;

    // Present the scene.
    [skView presentScene:scene];          

}

EDIT: Are you looking to make a custom initialization method that takes your array as a parameter? If so, add this to your scene subclass, and make a public declaration for it in your scene's header.

- (instancetype)initWithSize:(CGSize)size andCustomParameter:(NSArray *)theArray {
    self = [super initWithSize:size];

    if (self) {
        // do something with the array on iniitialization
    }

    return self;
}

Upvotes: 2

Related Questions