Using GameplayKit, I'm trying to make an enemy character pursue the player while avoiding obstacles in a SpriteKit game.
However, the agent
in agentDidUpdate(_:)
has a position and velocity of nan
.
Here's what I'm doing now:
- Configure the obstacles:
//node is defined here
let obstacle = GKCircleObstacle(radius: Float(node.size.width*0.5))
obstacle.position = vector_float2(x: Float(node.position.x), y: Float(node.position.y))
levelObstacles.append(obstacle)
- Configure a
GKEntity
(etc.) for the playerSKSpriteNode
, saving a reference to the component and agent for use in #3:
//node is defined here
let entity1 = GKEntity()
heroAgent = GKAgent2D()
heroComponent = GKSKNodeComponent(node: node)
heroAgent.delegate = self // <-- self is a GKAgentDelegate
node.entity = entity1
heroEntity = entity1
if let comp = heroComponent {
entity1.addComponent(comp)
entity1.addComponent(heroAgent)
}
- Configure a
GKEntity
(etc.) for the enemySKSpriteNode
, using the saved hero component and agent to set up the necessary behaviors:
//node is defined here
let entity = GKEntity()
let agent = GKAgent2D()
let avoid = GKGoal(toAvoid: levelObstacles, maxPredictionTime: 5.0)
let pursue = GKGoal(toInterceptAgent: heroAgent, maxPredictionTime: 5.0)
nodeComponent = GKSKNodeComponent(node: node)
agent.behavior = GKBehavior(goals: [avoid, pursue], andWeights: [100.0, 50.0])
agent.delegate = self // <-- self is a GKAgentDelegate
node.entity = entity
if let comp = nodeComponent {
entity.addComponent(comp)
entity.addComponent(agent)
}
nodeEntity = entity
- In the
SKScene
'supdate(_:)
method, call the enemy entity'supdate(deltaTime:)
method:
nodeEntity?.update(deltaTime: currentTime-lastFrameTime)
- Print the agent's position and velocity in
agentDidUpdate(_:)
:
func agentDidUpdate(_ agent: GKAgent) {
if let a = agent as? GKAgent2D {
print("agent position: \(a.position), agent velocity: \(a.velocity)") //Prints a position and velocity of "-nan"
}
}
Question: Why are the agent's position and velocity nan
inside agentDidUpdate(_:)
, and how do I solve the problem?
Update: The problem is apparently related to GKGoal(toInterceptAgent:maxPredictionTime:)
. If I use a different goal, like GKGoal(toFleeAgent:)
for example, there are actual values available in agentDidUpdate(_:)
.