Book Image

Unity AI Game Programming - Second Edition

By : Raymundo Barrera, Aung Sithu Kyaw, Clifford Peters, Thet Naing Swe
Book Image

Unity AI Game Programming - Second Edition

By: Raymundo Barrera, Aung Sithu Kyaw, Clifford Peters, Thet Naing Swe

Overview of this book

<p>Unity 5 provides game and app developers with a variety of tools to implement artificial intelligence. Leveraging these tools via Unity’s API or built-in features allows limitless possibilities when it comes to creating your game’s worlds and characters. Whether you are developing traditional, serious, educational, or any other kind of game, understanding how to apply artificial intelligence can take the fun-factor to the next level!</p> <p>This book helps you break down artificial intelligence into simple concepts to give the reader a fundamental understanding of the topic to build upon. Using a variety of examples, the book then takes those concepts and walks you through actual implementations designed to highlight key concepts, and features related to game AI in Unity 5. Along the way, several tips and tricks are included to make the development of your own AI easier and more efficient.</p> <p>Starting from covering the basic essential concepts to form a base for the later chapters in the book, you will learn to distinguish the state machine pattern along with implementing your own. This will be followed by learning how to implement a basic sensory system for your AI agent and coupling it with a finite state machine (FSM). Next you will be taught how to use Unity’s built-in NavMesh feature and implement your own A* pathfinding system. Then you will learn how to implement simple flocks and crowd’s dynamics, the key AI concepts. Then moving on you will learn how a behavior tree works and its implementation. Next you will learn adding layer of realism by combining fuzzy logic concepts with state machines. Lastly, you learn applying all the concepts in the book by combining them in a simple tank game.</p>
Table of Contents (15 chapters)
Unity AI Game Programming Second Edition
Credits
About the Authors
About the Reviewers
www.PacktPub.com
Preface
Index

Path following and steering


Sometimes, we want our AI characters to roam around in the game world, following a roughly-guided or thoroughly-defined path. For example, in a racing game, the AI opponents need to navigate on the road. In an RTS game, your units need to be able to get from wherever they are to the location you tell them to, navigating through the terrain, and around each other.

To appear intelligent, our agents need to be able to determine where they are going, and if they can reach that point, they should be able to route the most efficient path and modify that path if an obstacle appears as they navigate. As you'll learn in later chapters, even path following and steering can be represented via a finite state machine. You will then see how these systems begin to tie in.

In this book, we will cover the primary methods of pathfinding and navigation, starting with our own implementation of an A* Pathfinding system, followed by an overview of Unity's built-in navigation mesh (NavMesh) feature.

Using A* Pathfinding

There are many games where you can find monsters or enemies that follow the player, or go to a particular point while avoiding obstacles. For example, let's take a look at a typical RTS game. You can select a group of units and click on a location where you want them to move or click on the enemy units to attack them. Your units then need to find a way to reach the goal without colliding with the obstacles. The enemy units also need to be able to do the same. Obstacles could be different for different units. For example, an air force unit might be able to pass over a mountain, while the ground or artillery units need to find a way around it. A* (pronounced "A star") is a pathfinding algorithm, widely used in games because of its performance and accuracy. Let's take a look at an example to see how it works. Let's say we want our unit to move from point A to point B, but there's a wall in the way, and it can't go straight towards the target. So, it needs to find a way to get to point B while avoiding the wall. The following figure illustrates this scenario:

In order to find the path from point A to point B, we need to know more about the map such as the position of the obstacles. For this, we can split our whole map into small tiles, representing the whole map in a grid format. The tiles can also be of other shapes such as hexagons and triangles. Representing the whole map in a grid makes the search area more simplified, and this is an important step in pathfinding. We can now reference our map in a small 2D array.

Once our map is represented by a set of tiles, we can start searching for the best path to reach the target by calculating the movement score of each tile adjacent to the starting tile, which is a tile on the map not occupied by an obstacle, and then choosing the tile with the lowest cost. We'll dive into the specifics of how we assign scores and traverse the grid in Chapter 4, Finding Your Way, but this is the concept of A* Pathfinding in a nutshell.

A* Pathfinding calculates the cost to move across the tiles

A* is an important pattern to know when it comes to pathfinding, but Unity also gives us a couple of features right out of the box such as automatic navigation mesh generation and the NavMesh agent, which we'll explore in the next section and then in more detail in Chapter 4, Finding Your Way. These features make implementing pathfinding in your games a walk in the park (no pun intended). Whether you choose to implement your own A* solution or simply go with Unity's built in NavMesh feature, will depend on your project requirements. Each have their own pros and cons, but ultimately, knowing both will allow you to make the best possible choice. With that said, let's have a quick look at NavMesh.

Using navigation mesh

Now that we've taken a brief look at A*, let's look at some possible scenarios where we might find NavMesh a fitting approach to calculate the grid. One thing that you might notice is that using a simple grid in A* requires quite a number of computations to get a path that is the shortest to the target and at the same time, avoids the obstacles. So, to make it cheaper and easier for AI characters to find a path, people came up with the idea of using waypoints as a guide to move AI characters from the start point to the target point. Let's say we want to move our AI character from point A to point B and we've set up three waypoints, as shown in the following figure:

All we have to do now is to pick up the nearest waypoint and then follow its connected node leading to the target waypoint. Most of the games use waypoints for pathfinding because they are simple and quite effective in using less computation resources. However, they do have some issues. What if we want to update the obstacles in our map? We'll also have to place waypoints for the updated map again, as shown in the following figure:

Following each node to the target can mean that the AI character moves in a series of straight lines from node to node. Look at the preceding figures; it's quite likely that the AI character will collide with the wall where the path is close to the wall. If that happens, our AI will keep trying to go through the wall to reach the next target, but it won't be able to and will get stuck there. Even though we can smooth out the path by transforming it to a spline and do some adjustments to avoid such obstacles, the problem is that the waypoints don't give any information about the environment, other than the spline is connected between the two nodes. What if our smoothed and adjusted path passes the edge of a cliff or bridge? The new path might not be a safe path anymore. So, for our AI entities to be able to effectively traverse the whole level, we're going to need a tremendous number of waypoints, which will be really hard to implement and manage.

This is a situation where a NavMesh makes the most sense. NavMesh is another graph structure that can be used to represent our world, similar to the way we did with our square tile-based grid or waypoints graph, as shown in the following screenshot:

A navigation mesh uses convex polygons to represent the areas in the map that an AI entity can travel to. The most important benefit of using a navigation mesh is that it gives a lot more information about the environment than a waypoint system. Now we can adjust our path safely because we know the safe region in which our AI entities can travel. Another advantage of using a navigation mesh is that we can use the same mesh for different types of AI entities. Different AI entities can have different properties such as size, speed, and movement abilities. A set of waypoints is tailored for humans; AI may not work nicely for flying creatures or AI-controlled vehicles. These might need different sets of waypoints. Using a navigation mesh can save a lot of time in such cases.

But generating a navigation mesh programmatically based on a scene can be a somewhat complicated process. Fortunately, Unity 3.5 introduced a built-in navigation mesh generator as a Pro-only feature, but is now included for free in Unity 5 personal edition. Chapter 4, Finding Your Way, will look at some of the cool ways we can use Unity's NavMesh feature in your games and explore the additions and improvements that came with Unity 5.