GameplayKit GKPolygonObstacle不使用GKGoal

时间:2016-07-25 18:05:05

标签: ios objective-c sprite-kit game-physics gameplay-kit

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

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

我已调查Apple's 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的AgentCatalog源代码中提取的)

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

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

ISSUE

当我尝试使用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 GKPolygonObstacleGameplayKit个对象,因为我已经使用这种方法进行寻路(在我决定痛苦地实现之前) - (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; } 它寻求,避免和徘徊目标)。以下是我使用 innerMapArray

的方法
GKGoal

这种方法很好地返回了最有效的路径应该包含的点,以绕过我告诉敌人在尝试到达某个位置时要避免的障碍。

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

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

1 个答案:

答案 0 :(得分:2)

这是一个非常奇怪/简单的答案,我担心我现在已经被敌人避开(至少不是......)。

  • GKGoal避开障碍物 low maxPredictionTime(t <10)似乎使代理人完全忽略了障碍。任何10或更高的预测时间+ 100+的重量似乎都会导致正确的行为。