Creating the AI using cover

Having AI using cover is a huge step towards making characters seem more believable and it usually makes them more challenging as they don't die as quickly.

There are many ways to implement this functionality. In the simplest form, the AI is not aware of any cover. It's simply scripted (by a designer) to move to a predefined favorable position when they spot an enemy. A player playing the sequence for the first time can't possibly notice the difference between an AI taking the decision by itself. Hence, the task of creating a believable AI (for that situation) is accomplished.

A much more advanced way would be to use the same principles for cover, which was established in Chapter 2, Cameras and Game Controls. However, evaluating options also becomes far more complex and unpredictable. Unpredictable AI might be good from the player's perspective, but it's a nightmare from a designer's perspective.

In this recipe, we'll go for a middle ground. First of all, we will base the AI on the FSM created in the previous recipe, and add a new state that handles finding cover. We will then add cover points to a scene, from which the AI can pick a suitable one and move there before attacking.

Creating the AI using cover

State diagram

How to do it...

Let's begin by defining a class called CoverPoint, extending AbstractControl by performing the following steps:

  1. For now we can add a Vector3f called coverDirection. With getters and setters, that's all that's needed.
  2. We create a class called SeekCoverState, extending our AIState class from the previous recipe.
  3. It needs a list of CoverPoints called availableCovers, and a CoverPoint called targetCover.
  4. In the stateEnter method, it should look for a suitable cover point. We can do this with the following piece of code. It parses the list and takes the first CoverPoint where the dot product of the direction and coverDirection is positive:
    for(CoverPoint cover: availableCovers){
      if(aiControl.getTarget() != null){
        Vector3f directionToTarget = cover.getSpatial().getWorldTranslation().add(aiControl.getTarget().getWorldTranslation()).normalizeLocal();
                    if(cover.getCoverDirection().dot(directionToTarget) > 0){
          targetCover = cover;
          break;
        }
      }
    }
  5. In the controlUpdate method, the AI should move towards targetCover if it has one.
  6. Once it gets close enough, targetCover should be set to null, indicating it should switch to AttackState.
  7. When this happens, stateExit should tell the AI to stop moving.
  8. After adding the new state to the AI control class, to let it know it has the ability to seek cover, we also need to modify other states to enable it.
  9. Most suitable is PatrolState, where it can switch to SeekCoverState instead of AttackState when it spots a target.
  10. If we have a test case for the Finite State Machine, all we would now need to do is to add some CoverPoints to a scene and see what happens.

How it works...

The CoverPoint class we created adds the behavior to any Spatial instances to act as a cover. In a game, you would most likely not see the CoverPoint spatial, but it's good for debug and editing purposes. The concept can be expanded to cover other types of interest points for AI, as well as modified to handle volumes, rather than points using the spatial's geometry.

Once the SeekCoverState is enabled, it will try to find a suitable cover point that's relative to the target's position (at that time). It does this using the dot product between coverDirection and the direction to the target. If this is positive, it means the target is in front of the cover, and it picks this as targetCover.

When the AI reaches this, it sets targetCover to null. This means that when controlUpdate is called the next time, it will exit the state and enable AttackState instead. In a real game, the AI would most likely use some kind of navigation or pathfinding to get there. You can get an introduction to navigation in the next recipe. There is also the Pathfinding: Our own A* pathfinder recipe that covers implementing pathfinding later in the chapter.

With the current implementation of the AI, the result might be a bit erratic, since it doesn't remember the target's position. It might very well be that it doesn't see the target once it reaches the cover and instantly switches to PatrolState.

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

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