Препятствия с GameplayKit

Вот мой вопрос:

  • Как преобразовать SKSpriteNodeмассив в массив GKObstacles, чтобы агент мог должным образом обходить эти препятствия с помощью goalToAvoidObstacles:(nonnull NSArray<GKObstacle *> *) maxPredictionTime:(NSTimeInterval)/?

Кажется, что способ, которым я создаю массив GKObstacle, не позволяет GKGoal правильно идентифицировать их как препятствия, независимо от того, какой вес я придаю цели.

В настоящее время у меня есть несколько SKNode, которые добавлены в SKScene chapterScene. Каждый из этих узлов добавляется в сохраняемый мной массив под названием obstaclesArray. Я настроил тест следующим образом, который работает довольно хорошо:

ПРЕПЯТСТВИЯ ДЛЯ РАБОТЫ

- (void)didMoveToView:(nonnull SKView *)view {
    [super didMoveToView:view];

    // Add three obstacles in a triangle formation around the center of the scene.
    NSArray<GKObstacle *> *obstacles = @[
                                         [self addObstacleAtPoint:CGPointMake(CGRectGetMidX(self.frame),
                                                                              CGRectGetMidY(self.frame) + 150)],
                                         [self addObstacleAtPoint:CGPointMake(CGRectGetMidX(self.frame) - 200,
                                                                              CGRectGetMidY(self.frame) - 150)],
                                         [self addObstacleAtPoint:CGPointMake(CGRectGetMidX(self.frame) + 200,
                                                                              CGRectGetMidY(self.frame) - 150)],
                                         ];

    // The player agent follows the tracking agent.
    self.player = [[OPlayer alloc] initWithScene:self
                                                radius:50
                                              position:CGPointMake(CGRectGetMidX(self.frame),
                                                                   CGRectGetMidY(self.frame))];
    self.player.agent.behavior = [[GKBehavior alloc] init];
    [self.agentSystem addComponent:self.player.agent];

    // Create the seek goal, but add it to the behavior only in -setSeeking:.
    self.seekGoal = [GKGoal goalToSeekAgent:self.character];

    // Add an avoid-obstacles goal with a high weight to keep the agent from overlapping the obstacles.
    [self.player.agent.behavior setWeight:100 forGoal:[GKGoal goalToAvoidObstacles:obstacles maxPredictionTime:1]];

}

- (GKObstacle *)addObstacleAtPoint:(CGPoint)point {
    SKShapeNode *circleShape = [SKShapeNode shapeNodeWithCircleOfRadius:50];
    circleShape.lineWidth = 2.5;
    circleShape.fillColor = [SKColor grayColor];
    circleShape.strokeColor = [SKColor redColor];
    circleShape.zPosition = 1;
    circleShape.position = point;
    [self addChild:circleShape];

    GKCircleObstacle *obstacle = [GKCircleObstacle obstacleWithRadius:50];
    obstacle.position = (vector_float2){point.x, point.y};

    return obstacle;
}

Хотя это работает просто отлично, проблема, с которой я сталкиваюсь, заключается в том, что я не могу заставить поведение идентифицировать массив SKNode тел, который у меня есть как препятствия. Я могу только заставить эти созданные вручную GKCircleObstacle элементов регистрироваться как действительные препятствия, которых агент избегает. Причина, по которой это проблема, заключается в том, что я полагаюсь на множество препятствий, которые на самом деле не являются простыми кругами, а представляют собой многоугольные структуры, некоторые сложные, некоторые более простые. Тем не менее, я пытался сделать следующее, но мой агент, похоже, не избежал ни одного из препятствий, SKNode таким образом:

НЕ РАБОТАЮЩИЕ ПРЕПЯТСТВИЯ

NSArray *obstacles = [SKNode obstaclesFromNodePhysicsBodies:obstaclesArray];

/*
 The other code seen above
 */

// Add an avoid-obstacles goal with a high weight to keep the agent from overlapping the obstacles.
[self.player.agent.behavior setWeight:100 forGoal:[GKGoal goalToAvoidObstacles:obstacles maxPredictionTime:1]];

К сожалению, похоже, это не работает, так как независимо от того, насколько высок я устанавливаю вес, агент никогда не реагирует на избегание препятствий. Вот журнал массива, который я передаю ему:

2016-07-24 22:32:24.907 <GAME>[1516:475581] obstacles: (
    "<GKPolygonObstacle: 0x14d20d70>",
    "<GKPolygonObstacle: 0x14d20e10>",
    "<GKPolygonObstacle: 0x14d20ba0>",
    "<GKPolygonObstacle: 0x14d20bb0>",
    "<GKPolygonObstacle: 0x14d20bc0>",
    "<GKPolygonObstacle: 0x14d20a60>",
    "<GKPolygonObstacle: 0x14d208b0>",
    "<GKPolygonObstacle: 0x14d207d0>",
    "<GKPolygonObstacle: 0x14d20a70>"
)

Каждый из них был четко и правильно инициализирован и добавлен в сцену. Каждый из этих элементов на самом деле реагирует с помощью метода SpriteKit didBeginContact:(SKPhysicsContact *)contact, поэтому кажется, что узлы правильно обрабатывают границы, которые у них должны быть.

Если кто-то знает, что я делаю неправильно, или лучший способ превратить каждый из этих «узлов препятствий» в GKObstacle, я был бы очень признателен. Заранее спасибо!

ОБНОВЛЕНИЕ: Вот узел с физическим телом, которое я тестирую:

        SKSpriteNode *innerMap1 = [SKSpriteNode spriteNodeWithImageNamed:@"test"];
        innerMap1.physicsBody = [SKPhysicsBody bodyWithTexture:[SKTexture textureWithImageNamed:@"test"] size:CGSizeMake(innerMap1.frame.size.width*0.92, innerMap1.frame.size.height*0.92)];
        innerMap1.position = CGPointMake(-220, -140);
        innerMap1.physicsBody.dynamic = NO;

        [chapterSKSpriteNodes addObject:innerMap1];

Вот как выглядит тело с skView.showsPhysics = YES;:

введите здесь описание изображения

Так что я знаю, что физическое тело — это то, что мне нужно. Однако, когда я пытаюсь создать GKObstacle из этого тела, оно, кажется, не регистрируется как препятствие при назначении в цели избежать препятствий.


person Will Von Ullrich    schedule 25.07.2016    source источник
comment
Физические тела не бесплатны, вам нужно создать их для своих узлов. Я не вижу этого нигде в предоставленном коде   -  person Knight0fDragon    schedule 25.07.2016
comment
Извините - у меня ТОННЫ узлов с PB, поэтому я не предоставил код для их создания. Я приведу один пример в обновлении моего вопроса   -  person Will Von Ullrich    schedule 25.07.2016
comment
Может быть, у вас есть проблемы с порядком событий? Вы проверяете до obstaclesFromNodePhysicsBodies, чтобы увидеть, есть ли у высоких узлов в массиве тела?   -  person Knight0fDragon    schedule 25.07.2016
comment
Я не проверяю это нет, но сейчас я пытаюсь использовать объект, показанный на изображении выше, в качестве препятствия, и, похоже, он не принимает. Итак, из того, что я вижу, и из того, как я его настроил , я предполагаю, что у него есть тело, которое можно использовать   -  person Will Von Ullrich    schedule 25.07.2016
comment
хорошо, не думайте, требуется минута, чтобы проверить, существует ли физическое тело, написать цикл for и проверить, чтобы убедиться, что они существуют.   -  person Knight0fDragon    schedule 25.07.2016
comment
из того, что я вижу, они действительно существуют. Не уверен, что это то, что мне нужно сделать, но я просто сделал for (SKNode *node in obstaclesArray) { if (node.physicsBody) { NSLog(@"exists"); }} и получил их все   -  person Will Von Ullrich    schedule 25.07.2016
comment
какие-нибудь мысли о том, как заставить эти физические тела работать с GKGoal?   -  person Will Von Ullrich    schedule 25.07.2016
comment
без понятия, я не пользуюсь игровым набором, я могу только исходить из того, что показалось в вашем вопросе   -  person Knight0fDragon    schedule 25.07.2016
comment
Я испытываю то же самое, вы когда-нибудь решили эту проблему?   -  person Chris    schedule 16.08.2018
comment
Не совсем — кажется, что, поскольку GameKit все еще ребенок, я думаю, что такие вещи ожидаются. Надеюсь, их скоро починят..   -  person Will Von Ullrich    schedule 16.08.2018


Ответы (1)


Это похоже на ошибку. Вы должны проверить возвращаемый массив из препятствийFromNodePhysicsBodies и убедиться, что вы действительно возвращаете ожидаемые препятствия. Подозреваю, что нет.

Вы можете проверить соответствующие вершины на ваших препятствиях как таковые:

https://developer.apple.com/library/ios/documentation/GameplayKit/Reference/GKPolygonObstacle_Class/index.html#//apple_ref/occ/cl/GKPolygonObstacle

Убедитесь, что они соответствуют вашим ожиданиям.

person Whirlwind    schedule 03.08.2016