3

与我在这里发布的问题类似,我现在意识到这个问题比我预期的更微不足道,因为这适用于某些元素GameplayKit但不适用于其他元素。

我有一个障碍物 an SKNode,我试图将它定义为一个GKPolygonObstacle可以被代理使用的 a GKAgent2D,作为在SKScene我设置的移动时要避免的障碍物。

我查看了Apple 的 AgentsCatalog以了解他们如何GKObstacle在方法中使用代理GameplayKit

goalToAvoidObstacles:(nonnull NSArray<GKObstacle *> *) maxPredictionTime:(NSTimeInterval)

当我在自己的项目中使用以下代码创建GKCircleObstacle对象时,我发现代理可以很好地导航并很好地避开这些圆形障碍物,具体取决于我赋予它的权重(重要性级别)。

这是我正在使用的代码:

NSArray<GKObstacle *> *obstacles2 = @[
    [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)], ];
  
enemy.avoidGoal = [GKGoal goalToAvoidObstacles:obstacles2 maxPredictionTime:1];
[enemy.agent.behavior setWeight:100 forGoal:enemy.avoidGoal];

使用以下方法创建和添加这些障碍:(这是直接从 Apple 的 AgentsCatalog 源代码中提取的)

- (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;
}

当敌人试图移动到场景中某个变化的位置时,它会避开这些圆圈,这很有效。

问题

当我尝试GKGoal通过使用GKPolygonObstacle对象代替对象来重新创建此行为时GKCircleObstacle,敌方代理似乎无法将多边形障碍识别为行为目标要避免的障碍。以下是我尝试添加这些障碍的方法:

NSArray<GKObstacle *> *obstacles = [SKNode obstaclesFromNodePhysicsBodies:innerMapArray];

// Take this array of GKPolygonObstacle objects and add it 
// to the GKGoal of the enemy as obstacles to avoid

enemy.avoidGoal = [GKGoal goalToAvoidObstacles:obstacles maxPredictionTime:1];
[enemy.agent.behavior setWeight:100 forGoal:enemy.avoidGoal];

最令人沮丧的是,我知道数组正确地创建了一个NSArray对象GKPolygonObstacle,因为我也使用这种方法进行寻路(在我决定痛苦地实现GameplayKit它是寻找、避免和徘徊目标之前)。这是我使用这个innerMapArray 的方式

- (NSArray *)findPathWithNode:(SKNode *)nodeToFindPath {
    
    NSArray *obstacles = [SKNode obstaclesFromNodePhysicsBodies:innerMapArray];
    GKObstacleGraph *graph = [GKObstacleGraph graphWithObstacles:obstacles bufferRadius:35.0f];


    // Set up enemy and target
    GKGraphNode2D *target = [GKGraphNode2D nodeWithPoint:vector2((float)character.position.x, (float)character.position.y)];
    GKGraphNode2D *enemy = [GKGraphNode2D nodeWithPoint:vector2((float)nodeToFindPath.position.x, (float)nodeToFindPath.position.y)];
    
    [graph connectNodeUsingObstacles:enemy];
    [graph connectNodeUsingObstacles:target];
    
    /// Create tracking path
    NSArray *pathPointsFound = [graph findPathFromNode:enemy toNode:target];

    
    return pathPointsFound;
}

这个方法很好地返回了最有效的路径应该包括绕过障碍物的点,我告诉敌人在试图到达一个位置时要避开。

  • 所以真正的问题变成了:为什么GKGoal接受GKCircleObstacle对象而不接受GKPolygonObstacle对象?

如果有人可以帮助我弄清楚如何将这些SKNode对象转换为注册的可接受的障碍物,GKGoal我将非常感激。谢谢你。

4

1 回答 1

3

这是一个非常奇怪/简单的答案,恐怕我现在有障碍物被敌人避开(至少不是......)。

  • GKGoal避开障碍物一个非常 maxPredictionTime的(t < 10)似乎使代理完全忽略障碍物。任何 10 或更大的预测时间 + 100+ 的权重似乎都会导致正确的行为。
于 2016-07-26T20:43:03.950 回答