Run action only on parent sknode

As title says. How to run SKAction only on parent only (children not affected by it)?

I have some SKSpriteNodes with children, but I would like to manually control which actions are run on each children and that actions are not inherited from parent

Answered by QuinceyMorris in 120750022

Actions are not inherited from the parent, really, but the effects of property changes are. So you have 2 choices:


1. When you add an action to the parent, add an inverse of the action to the children. That is, if you move the parent 10 to the left, move the children 10 to the right.


2. Rethink your design. If the children don't reflect changes to parent properties, they probably shouldn't be children.


If you have other reasons for associating these "children" with this "parent", then I suggest you create a plain SKNode, and make the children subnodes of that. Then create another plain SKNode, and make the parent and first SKNode children of that. With that structure, you can chose which parts of the hierarchy you want actions to affect.

I'm not fully understanding what you mean. Can you tell us more about what you want to achieve, maybe an example?

Accepted Answer

Actions are not inherited from the parent, really, but the effects of property changes are. So you have 2 choices:


1. When you add an action to the parent, add an inverse of the action to the children. That is, if you move the parent 10 to the left, move the children 10 to the right.


2. Rethink your design. If the children don't reflect changes to parent properties, they probably shouldn't be children.


If you have other reasons for associating these "children" with this "parent", then I suggest you create a plain SKNode, and make the children subnodes of that. Then create another plain SKNode, and make the parent and first SKNode children of that. With that structure, you can chose which parts of the hierarchy you want actions to affect.

Imagine parent being a rock or round object travelling on oval around other object and also rotating around own axis (2 actions).

first children is shadow sprite that is traveling with parent on oval, but rotating differently (light source is from center of oval so shadow should be always on outside of oarent object).

In addition to that, player has option to be able to click on that object, and first action that is on is blinking action when player is howering with mouse over sprite. Second child is made visible when player clicks on objects (it is just a simple square box around boject) that should travel with object, but not rotate or blink with it.

I agree with QuinceyMorris, and would personally go with option 2. If your orbiting element needs to act on its own, and there's a separate shadow object, which is really mainly affected by the parent of the rotation, the shadow shouldn't be a child of the orbiting element that acts on its own.


I would suggest this structure:


[sunNode]

[planetNode]

[planetImage]

[planetShadow]


So:

1) planetNode rotates around sunNode

2) planetImage rotates around itself

3) planetShadow stays in place


And then if you would like the planetShadow to rotate as well to match a non-circular planetImage, just apply the same rotation action to both elements.

Right now I have:

planetNode that has action to follow a path (oval) and another action to rotate by angle all the time. This node is inherited from SKSpriteNode, it also has added other things:

- a mouse over effect (action for blinking node when mouse is over planet)

- a mouse click (an action that should stop blinking and instead show child that is actually a square that is drawn around planet, but it should move with planet all the time when it is selected).


I have disengaged planet shadow node (this is normal SKSpriteNode now) and it is just following planet on same path action, but it has own rotating action.


All fine and good, but now selecting and hovering isn't working, as planet is under shadow node. Ok I understand, that I'm trying to have events on object that doesn't have them, but making shadow clickable and hoverable object type is defeating a purpose of selecting a planet as I then don't know which planet is actually under that shadow. Shadow can be same on multiple planets. Only solution I can find now is to make shadow clickable/hoverable object and put a name to it and then search for a planet with the same name.

As for selecting I'm thinking of disengage it as well from planet node, but that would make it harder to follow selected object. Is there a way to copy actions from one object to another? I know I can just say selector.position = shadow.position, this moves it to selected planet, but then it should follow it with the same skaction that is already on that node.

Ok I have changed design, but now I have another problem. Copy action from one spritenode to another.

Doing this doesn't work:

onesprite.runAction(othersprite.actionForKey("someaction")!)


This is the last piece I need for this to work. 🙂

Doesn't work how?


If the problem is that it won't let you attach the same action to different nodes, you can try using a copy of the action:


othersprite.actionForKey("someaction")!.copy ()


(SKAction conforms to NSCopying, so you always copy it.)


If that doesn't work, you're going to have to create a new action that's just like the old action — which is a lot more work, if it's not obvious what the old action does.

Actually I'm sorry, it works, but problem is sync with animations.

Funny thing is, that "planet" now rotates around on path and when I select sprite it should put same follow path action to selector sprite - which does, but I cannot set from where this action should start (not from the start but from the location where "planet" is). Setting position doesn't do the trick here.

Put the path animation action on a SKNode that has the planet node as a child, then attach other nodes to the same SKNode to get the same path.


This works only if all such "groupings" are hierarchical. Otherwise you're going to have to do something more complicated, such as a custom action that runs every frame and transfers one node's position to another node.

Run action only on parent sknode
 
 
Q