Transition Scene From Child Node

Hey,


I have an SKScene and a class that subclasses SKNode. The SKNode is added to the SKScene. I want to be able to transition the scene to a new scene from the SKNode. I don't need to preserve any data about the SKNode.


I would like to use something like this...

SKScene *shopScene = [[ShopScene alloc] initWithSize:self.size];
    SKTransition *transition = [SKTransition fadeWithDuration:0];
    [self.view presentScene:shopScene transition:transition];


But it only works when being called from the SKScene itself, not the SKNode. I get the error "Property 'size' not found on object of type 'overRoundLayer *'" The error is thown on self.size.


Thanks!

Accepted Reply

It's inaccurate think in terms of transitioning to a new scene "from the SKNode". You always transition from scene to scene, regardless of how you choose to conceptualize it. This is clear when you look at your code:


    [self.view presentScene:shopScene transition:transition];


The current SKNode subclass isn't involved in this — it's the view that initiates the transition.


Anyway, the error you're seeing is unrelated to the transition:


     SKScene *shopScene = [[ShopScene alloc] initWithSize:self.size];


Presumably your intention is to use the current scene's size for the new scene, and every SKNode has a "scene" property, so:


     SKScene *shopScene = [[ShopScene alloc] initWithSize:self.scene.size];

Replies

It's inaccurate think in terms of transitioning to a new scene "from the SKNode". You always transition from scene to scene, regardless of how you choose to conceptualize it. This is clear when you look at your code:


    [self.view presentScene:shopScene transition:transition];


The current SKNode subclass isn't involved in this — it's the view that initiates the transition.


Anyway, the error you're seeing is unrelated to the transition:


     SKScene *shopScene = [[ShopScene alloc] initWithSize:self.size];


Presumably your intention is to use the current scene's size for the new scene, and every SKNode has a "scene" property, so:


     SKScene *shopScene = [[ShopScene alloc] initWithSize:self.scene.size];

Thanks a ton. I'm refractoring / rewriting a crazy old app that wasn't written very well, I just needed a quick fix for now. I used the below code and things seem to be working.


SKScene *shopScene = [[ShopScene alloc] initWithSize:self.scene.size];
    SKTransition *transition = [SKTransition fadeWithDuration:0];
    [self.scene.view presentScene:shopScene transition:transition];


But for future reference, how can I do it better? The SKNode represents a menu with buttons, and when one of which is pressed the scene should change. It made sense to change the scene from the SKNode since that's where the callback is. Would it be better to have a method to switch scenes in the main SKScene and call that method from the SKNode? If so, what's the best way to do that?


Like I said, thanks a ton!

Actually, this code is fine. The code is in the SKNode subclass, because that's where the triggering event or condition is handled. My point was that the transition is from scene to scene, and the new scene is actually presented by the SKView, so in a different sense the transition isn't "from" the SKNode.


At a slightly higher design level, it could perhaps be argued that having this transition code "buried" in the SKNode subclass is a little bit obscure. For example, if someone trying to understand your code wanted to know how the transition happened, they might not expect to look in the SKNode subclass for that code. You might consider re-packaging this code as a method in either your old scene's class (the one being transitioned from) or the ShopScene class, or (better still) the view controller, since it is generally in charge of getting a scene presented.


You would invoke this method from the same place in your SKNode subclass as your current code, but the implemention would be in a more expected context.


This is actually a intrinsic philosophical issue with Sprite Kit. The view controller, the SKView and the (current) SKScene are all in some sense "in charge", so deciding where to put top-level control functionality can be hard.