Use Multiple Goals

The thing about AI and autonomy is that once you give an object a little freedom, it’s no longer subject to your direct commands. Instead, it’s designed to think and act on its own. Sure, you may give it a goal, and it will attempt to meet that goal, but you’re no longer the one in charge.

Earlier, you “asked” the monsters to wander around by giving them a goal. So far, so good. The next goal you have for them is to chase Val, but only if she has a set of keys.

Still inside the AgentComponent.swift file, locate the following line:

 agent.behavior = ​GKBehavior​(goal: wanderGoal, weight: 100)

and replace it with this one:

 agent.behavior = ​GKBehavior​(goals: [wanderGoal, interceptGoal],
  andWeights: [100, 0])

Now, instead of setting the agent’s behavior with one goal, you’re using two. Also notice that each goal has a weight associated with it. The weight determines a goal’s priority: the higher the number, the more of a priority it is for the agent.

Here, the wander goal has a much higher weight (100 vs 0), which means this agent (the monster) is more likely to wander than it is to track the other agent (Val)—at least at first.

Remember, the “behavior” you want your monsters to achieve is that when Val has keys in her pocket, they’re more likely to chase her than when she doesn’t have keys. I use the phrase more likely because the agents are responsible for the thinking, not you. Your job was to give them a set of goals; their job is to figure out what to do and where to travel based on those goals—and what better way to handle that logic than in the component’s update(deltaTime:) method, which you’ll need to override, of course.

Below the didAddToEntity() method, add the following code:

 override​ ​func​ ​update​(deltaTime seconds: ​TimeInterval​) {
 guard​ ​let​ scene = componentNode.scene ​as?​ ​GameScene​,
 let​ player = scene.​childNode​(withName: ​"player"​) ​as?​ ​Player​ ​else​ {
 return
  }
 
 switch​ player.stateMachine.currentState {
 case​ ​is​ ​PlayerHasKeyState​:
  agent.behavior?.​setWeight​(100, for: interceptGoal)
 
 default​:
  agent.behavior?.​setWeight​(0, for: interceptGoal)
 break
  }
 }

This code checks the current state of the player.stateMachine object using the following logic: when Val has keys, you increase the weighted value of the intercept goal to match the wander goal; when she doesn’t have keys, you decrease that value back to 0. A value of 0 almost guarantees the agent will ignore the goal completely.

Before you can test this new monster behavior, you first need to have the player’s agent participate in the update routine so that the monster agents know what to do and where to go.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset