昨日調べた事の続きです。
この記事では、GKGoalを使って特定のオブジェクトに向かって移動するAgentを作成しました。
今回は「特定のオブジェクトに向かって移動」「別のオブジェクトから逃げる」の複数を指定した場合を試してみます。
GKGoalとGKAgentで目的に向かって動くオブジェクトを作ってみる - しめ鯖日記
昨日同様に、Gameプロジェクトを作成します。
GameScene.swiftを以下のように置き換えます。
昨日の記事と違い、GKBehaviorに複数のGKGoalを与えています。
こうする事でagent3にagent2から遠ざかりつつagent1へ移動する動きをさせる事ができます。
import SpriteKit import GameplayKit class GameScene: SKScene { let agentSystem = GKComponentSystem(componentClass: GKAgent2D.self) let agent1 = GKAgent2D() let agent2 = GKAgent2D() let agent3 = GKAgent2D() let node1 = SKSpriteNode(color: UIColor.brown, size: CGSize(width: 10, height: 10)) let node2 = SKSpriteNode(color: UIColor.green, size: CGSize(width: 10, height: 10)) let node3 = SKSpriteNode(color: UIColor.red, size: CGSize(width: 10, height: 10)) var prevTime: TimeInterval = 0 override func didMove(to view: SKView) { agent1.position = vector_float2(x: 100, y: 100) agent2.position = vector_float2(x: 300, y: 100) node1.position = CGPoint(x: Double(agent1.position.x), y: Double(agent1.position.y)) node2.position = CGPoint(x: Double(agent2.position.x), y: Double(agent2.position.y)) agent3.position = vector_float2(x: 300, y: 500) agent3.maxAcceleration = 10 agent3.maxSpeed = 10 agent3.delegate = self agent3.behavior = GKBehavior(goals: [ GKGoal(toSeekAgent: agent1), GKGoal(toFleeAgent: agent2) ], andWeights: [100, 10] ) agentSystem.addComponent(agent3) addChild(node1) addChild(node2) addChild(node3) } override func update(_ currentTime: TimeInterval) { let deltaTime = prevTime == 0 ? 0 : currentTime - prevTime prevTime = currentTime agentSystem.update(deltaTime: deltaTime) } } extension GameScene: GKAgentDelegate { func agentDidUpdate(_ agent: GKAgent) { if let agent = agent as? GKAgent2D { node3.position = CGPoint(x: Double(agent.position.x), y: Double(agent.position.y)) print(agent.position) } } }
この状態で起動するとagent2を避けつつagent1に向かう動きをします。
下図の右上がagent3、右下がagent2、左下はagent1を表しています。
もしここでandWeightsを両方100にした場合は少し動きが変わってきます。
agent3.behavior = GKBehavior(goals: [ GKGoal(toSeekAgent: agent1), GKGoal(toFleeAgent: agent2) ], andWeights: [100, 100] )
agent1に近づく動きとagent2から遠ざかる動きが重なり、下図のように真っ直ぐ左側に移動する事になります。