How to rotate a SKNode that has an SKEffectNode child

344 Views Asked by At

I have a SKNode that I want to use to organise a number of other SKSpriteNodes and SKEffectNodes. The ultimate aim is to have a character sprite can change colour of just parts of its body (hence the SKEffectNode) plus lots of other behaviours (hence adding them all to a parent SKNode)

I want to organise the complex and compound behaviour in an SKNode for organisational and learning reasons.

Here's my code:

@interface TestNode : SKNode

-(void)rotate;
- (instancetype)initWithPosition:(CGPoint)position;

@end

@implementation TestNode {
    SKSpriteNode *_shape1;
    SKSpriteNode *_shape2;
    CIFilter *_hueFilter;
    SKEffectNode *_effectNode;
}

- (instancetype)initWithPosition:(CGPoint)position;
{

    /* Setup your scene here */
    self.position = position;
    self.name = @"compoundNode";

    _shape1 = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(80, 30)];
    [self addChild:_shape1];

    _shape2 = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(20, 50)];

    BOOL useEffectNode = YES;
    if (useEffectNode) {
        _effectNode = [SKEffectNode node];
        [_effectNode addChild:_shape2];

        _hueFilter = [CIFilter filterWithName:@"CIHueAdjust"];
        [_hueFilter setValue:@0 forKey:@"inputAngle"];
        _effectNode.filter = _hueFilter;
        _effectNode.shouldEnableEffects = YES;
        [self addChild:_effectNode];
    } else {
        [self addChild:_shape2];
    }
    return self;
}

-(void) rotate {
    float angle = self.zRotation;
    angle = angle + 0.1;
    [self runAction:[SKAction rotateToAngle:angle duration:0.1]];
    [self updateColor];
}

-(void) updateColor {
    float randVal = RandomRange(0, 6.14);
    [_hueFilter setValue:[NSNumber numberWithFloat:randVal] forKey:@"inputAngle"];
}

@end

When this is run and the rotate method called (e.g. from touchesBegan on the scene) the red shape1 rotates as expected but the green shape2 goes a bit crazy. To look at, it seems to be scaled via X then by Y, but no rotation.

Here is the starting image Here is the starting image

and after some rotation and after some rotation

I've tried logging the zRotation of all the nodes, the parent is updated and all the children remain at 0.0. This is what I expected.

I know I can just change the color of the shape2 node to get around this particular problem, but I still want to understand what's happening for the future.

I know that when I take the SKEffectNode out of the equation it all works as expected, so my question is how can I use an SKEffectNode in this node tree and have the parent respond to zRotation in a sane manner?

One thought I've had is the issue lies with the CIFilter rendering output based on the stored inputImage, which doesn't get rotated, but I'm really guessing now.

0

There are 0 best solutions below