2015-02-22 5 views
7

У меня не получилось получить SKSpriteNode, чтобы отбросить тень, а также исчезнуть при входе в тень от того же источника света. Я могу сделать один из двух, но не оба.SKLightNode cast shadow issue

В соответствии с документами: Если спрайт находится внутри тени, отлитой от света, а спрайт имеет более низкое положение z, чем свет, тень влияет на то, как спрайт горит. Все, что я сделал. Мой SKLightNode имеет zPosition 100, а все остальные узлы имеют более низкие значения zPosition.

Я пробовал любые комбинации настроек для lightingBitMask, shadowCastBitMask и shadowedBitMask, но ничего не сработало.

Я размещаю изолированный код, который воссоздает мою проблему. Синяя коробка бросает тень, но не покрывается тенью стены. Фиолетовая коробка не оставляет тени и закрыта тенью стены.

Свет реагирует на движение касания, поэтому не стесняйтесь перемещать его по экрану. Проект находится в ландшафтном режиме.

Что мне не хватает или не вижу?

#import "GameScene.h" 

@implementation GameScene { 
    SKSpriteNode *lightBulb; 
} 

-(void)didMoveToView:(SKView *)view { 

    typedef NS_OPTIONS(uint32_t, Level1LightCategory) 
    { 
     CategoryLightPlayer   = 1 << 0, 
    }; 

    SKSpriteNode *worldNode = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(1136, 640)]; 
    worldNode.zPosition = 10; 
    //worldNode.position = CGPointMake(self.size.width/2, self.size.height/2); 
    [self addChild:worldNode]; 

    lightBulb = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(20, 20)]; 
    lightBulb.zPosition = 100; 
    lightBulb.position = CGPointMake(50, 50); 
    [worldNode addChild:lightBulb]; 

    SKLightNode *light = [[SKLightNode alloc] init]; 
    //light.zPosition = 100; // <- tried setting this again but to no effect 
    light.categoryBitMask = CategoryLightPlayer; 
    light.falloff = 0.3; 
    light.ambientColor = [UIColor whiteColor]; 
    light.lightColor = [[UIColor alloc] initWithRed:1.0 green:1.0 blue:1.0 alpha:1.0]; 
    light.shadowColor = [[UIColor alloc] initWithRed:0.0 green:0.0 blue:0.0 alpha:1.0]; 
    [lightBulb addChild:light]; 

    SKSpriteNode *wall = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(10, 300)]; 
    wall.zPosition = 50; 
    wall.position = CGPointMake(500, 200); 
    wall.lightingBitMask = CategoryLightPlayer; 
    wall.shadowCastBitMask = CategoryLightPlayer; 
    wall.shadowedBitMask = 0x00000000; 
    [worldNode addChild:wall]; 

    SKSpriteNode *box0 = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(30, 30)]; 
    box0.zPosition = 40; 
    box0.position = CGPointMake(800, 200); 
    box0.lightingBitMask = CategoryLightPlayer; 
    box0.shadowCastBitMask = CategoryLightPlayer; 
    box0.shadowedBitMask = CategoryLightPlayer; 
    [worldNode addChild:box0]; 

    SKSpriteNode *box1 = [SKSpriteNode spriteNodeWithColor:[SKColor purpleColor] size:CGSizeMake(30, 30)]; 
    box1.zPosition = 40; 
    box1.position = CGPointMake(800, 300); 
    box1.lightingBitMask = CategoryLightPlayer; 
    //box1.shadowCastBitMask = CategoryLightPlayer; 
    //box1.shadowedBitMask = CategoryLightPlayer; 
    [worldNode addChild:box1]; 
} 

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    CGPoint touchLocation = [touch locationInNode:self.scene]; 

    lightBulb.position = touchLocation; 
} 

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    CGPoint touchLocation = [touch locationInNode:self.scene]; 

    lightBulb.position = touchLocation; 
} 

-(void)update:(CFTimeInterval)currentTime { 
    // 
} 

@end 

ответ

9

Я только что услышал от технической поддержки Apple Developer, подтверждающей, что это ошибка в SpriteKit (SKLightNode). В настоящее время они не знают об обходном пути для этой проблемы, но будут обновлять меня, если они будут найдены.

По их запросу я подал отчет об ошибке.

UPDATE 22 апреля 2015

SK инжиниринговая подтвердил, что SpriteKit не поддерживает отбрасывание теней и тени на одном объекте. В настоящее время нет обходного пути. В какой-то момент этот вопрос будет рассмотрен.

UPDATE 15 декабря 2015

Получен новый ответ от компании Apple по этому вопросу.

компании Apple Developer Relations 14-Dec-2015 1:35 вечера

Там нет никаких планов по решению этого.

Мы закрываем этот отчет.

+1

Я проверил это, используя Xcode 8.3.2, и, похоже, он исправлен. Я помещаю ваш код в примерный проект, и отбрасывание тени из стены над синим ящиком скрывает его, как ожидалось. Синяя коробка также по-прежнему бросает свою тень, когда она не закрыта тенью стены. Возможно, это было исправлено в недавнем обновлении SK или, возможно, я не понимаю вашу проблему. – Jonathan

-1

I'v нашел некоторые обходной путь (не уверен, что это полезно для всех ситуации, но в некоторых): Вы можете сделать два (или больше - до 32, как мы знаем) различные источники света и назначить вам спрайтов их по одному (или некоторыми группами). Затем тени будут сочетаться по мере необходимости - правильно.

SKLightNode* light1 = [SKLightNode new]; 
SKLightNode* light2 = [SKLightNode new]; 

... // init them equally 

light1.categoryBitMask = 1; 
light2.categoryBitMask = 2; 
... 

SKSpriteNode* sprite1 = ... 
SKSpriteNode* sprite2 = ... 

sp1.shadowCastBitMask = 1; 
sp1.shadowedBitMask = 1; 
sp2.shadowCastBitMask = 2; 
sp2.shadowedBitMask = 2; 
+0

Это не решение. Проблема заключается в том, что узел бросает тень, он не может быть затенен одновременно. Создание 2 узлов не решает его, поскольку узел, бросающий тень, не исчезнет в тени. – sangony

 Смежные вопросы

  • Нет связанных вопросов^_^