Ios 使用GameplayKit设置障碍

Ios 使用GameplayKit设置障碍,ios,objective-c,sprite-kit,gameplay-kit,Ios,Objective C,Sprite Kit,Gameplay Kit,我的问题是: 如何将SKSpriteNode数组转换为gk障碍数组,以便代理可以通过使用goaltoavoidobstractes:(非空NSArray*)maxPredictionTime:(NSTimeInterval)/ 似乎我创建gk障碍物数组的方式不允许gk目标正确识别这些障碍物,无论我对目标的权重如何 我目前有几个SKNode被添加到SKScene章场景中。这些节点中的每一个都被添加到我正在存储的名为obstaclesArray的数组中。我以以下方式设置了一个测试,效果非常好:

我的问题是:

  • 如何将
    SKSpriteNode
    数组转换为
    gk障碍数组
    ,以便代理可以通过使用
    goaltoavoidobstractes:(非空NSArray*)maxPredictionTime:(NSTimeInterval)
    /
似乎我创建
gk障碍物
数组的方式不允许
gk目标
正确识别这些障碍物,无论我对目标的权重如何

我目前有几个
SKNode
被添加到
SKScene
章场景中。这些节点中的每一个都被添加到我正在存储的名为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;
}
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>"
)
下面是身体在
skView.showsPhysics=YES时的样子


所以我知道物理体就是我所需要的。然而,当我试图从这个身体中创建障碍时,它似乎并没有在分配到Avoidobstacks目标时注册为障碍。

这听起来像一个bug。您应该检查来自obstaclesfromNodePhysicsBody的返回数组,并确保您实际获得了预期的障碍物。我想你不是

您可以检查障碍物上的相关顶点,例如:


确保它们符合您的期望。

这听起来像个bug。您应该检查来自obstaclesfromNodePhysicsBody的返回数组,并确保您实际获得了预期的障碍物。我想你不是

您可以检查障碍物上的相关顶点,例如:


确保它们是您所期望的。

物理实体不是免费的,您需要为节点创建它们。我在提供的代码中没有看到这一点对不起,有很多带有PB的节点,所以我没有提供代码来制作它们。在更新我的问题时,我会举一个例子,也许你对事件的顺序有意见?在
obstacles fromNodePhysicsBodys
之前,您是否检查数组中的节点是否有实体?我没有检查此项否,但我现在正尝试将上图中显示的对象用作障碍物,它似乎没有移动..因此,从我看到的情况和我设置它的方式来看,我假设它确实有一个可以使用的实体。不要假设,验证物理实体是否存在需要一分钟的时间,写一个for循环并检查它们是否存在。物理实体不是免费的,您需要为节点创建它们。我在提供的代码中没有看到这一点对不起,有很多带有PB的节点,所以我没有提供代码来制作它们。在更新我的问题时,我会举一个例子,也许你对事件的顺序有意见?在
obstacles fromNodePhysicsBodys
之前,您是否检查数组中的节点是否有实体?我没有检查此项否,但我现在正尝试将上图中显示的对象用作障碍物,它似乎没有移动..因此,从我看到的情况和我设置它的方式来看,我假设它确实有一个可以使用的物体。不要假设,它需要一分钟来验证物理物体是否存在,写一个for循环并检查它们是否存在。
        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];