3

ここに投稿した質問と同様に、これは一部の要素では機能しますが、他の要素では機能しないため、問題が予想よりも簡単であることに気付きGameplayKitました..

私は、エージェントが使用できるSKNodeとして定義しようとしている障害物を持っています。GKPolygonObstacleGKAgent2DSKScene

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];

これらの障害を作成および追加する次のメソッドを使用します: (これは、AgentsCatalog の Apple のソース コードから直接取得されます)。

- (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動作を再現しようとすると、敵のエージェントはポリゴンの障害物を、動作の目標を回避するための障害物として識別できないようです。これらの障害を追加しようとしている方法は次のとおりです。GKPolygonObstacleGKCircleObstacle

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];

これについて最もイライラするのは、パスファインディングにもこのアプローチを使用したため、配列がオブジェクトNSArrayGKPolygonObstacleオブジェクトを正しく作成していることを知っていることです (苦労して実装することを決定する前に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を受け入れないのはなぜですか?GKCircleObstacleGKPolygonObstacle

誰かがこれらのSKNodeオブジェクトを に登録する許容可能な障害物に変換する方法を理解するのを手伝ってくれるなら、GKGoal私は非常に感謝しています. ありがとうございました。

4

1 に答える 1