ここに投稿した質問と同様に、これは一部の要素では機能しますが、他の要素では機能しないため、問題が予想よりも簡単であることに気付きGameplayKit
ました..
私は、エージェントが使用できるSKNode
として定義しようとしている障害物を持っています。GKPolygonObstacle
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];
これらの障害を作成および追加する次のメソッドを使用します: (これは、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
動作を再現しようとすると、敵のエージェントはポリゴンの障害物を、動作の目標を回避するための障害物として識別できないようです。これらの障害を追加しようとしている方法は次のとおりです。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
私は非常に感謝しています. ありがとうございました。