Love God more than you love anything else. Always say God ...
SCHOOL OF COMPUTING UNIVERSITY OF TEESSIDE...
Transcript of SCHOOL OF COMPUTING UNIVERSITY OF TEESSIDE...
SCHOOL OF COMPUTING
UNIVERSITY OF TEESSIDE
MIDDLESBROUGH
TS1 3BA
Cover-based Pathfinding
BSc. Computer Games Programming
Charlotte Lacombe--Bar
28th
May 2012
Supervisor: Dr. Jean-Luc Lugrin
Second Reader: Wen Tang
SCHOOL OF COMPUTING
UNIVERSITY OF TEESSIDE
MIDDLESBROUGH
TS1 3BA
Cover-based Pathfinding
BSc. Computer Games Programming
Charlotte Lacombe--Bar
28th
May 2012
Supervisor: Dr. Jean-Luc Lugrin
Second Reader: Wen Tang
i
ABSTRACT
Most of today’s FPS-like games now implement a cover system accessible for
both the AI and player. In order for the AI to look as “intelligent” and human-
like as possible, it should take full advantage of the given cover system when
navigating the game environment.
The objective of this project is to develop a pathfinding algorithm derived from
A Star that will take into account cover points. The report will look at different
world discretization and pathfinding techniques before following the design,
implementation and testing of the chosen technique/algorithm.
The algorithm will be demonstrated on the 3d game engine Unity.
2
ACKNOWLEDGEMENTS
I would like to thank my supervisor for overseeing this project and supporting
me.
3
CONTENTS
ABSTRACT ...................................................................................................... I
ACKNOWLEDGEMENTS ............................................................................... 2
1 INTRODUCTION ...................................................................................... 4
1.1 Cover in Games ................................................................................ 4
1.2 Problem Overview ............................................................................ 5
1.3 Requirements ................................................................................... 5
2 METHODOLOGY ..................................................................................... 6
2.1 Unity .................................................................................................. 6
2.2 Evolutionary prototyping ................................................................. 6
2.3 Testing ............................................................................................... 8
3 RESEARCH ............................................................................................. 9
3.1 Pathfinding in Unity .......................................................................... 9
3.2 World Discretization ....................................................................... 10
3.2.1 Grids ......................................................................................... 10
3.2.2 Waypoints ................................................................................. 12
3.2.3 Navigation Meshes .................................................................. 13
3.3 Pathfinding algorithm .................................................................... 14
3.3.1 AStar ......................................................................................... 14
3.3.2 Heuristics ................................................................................. 16
3.3.3 Tactical Pathfinding ................................................................. 17
4 DESIGN .................................................................................................. 19
4.1 World Discretization ....................................................................... 21
5 IMPLEMENTATION ............................................................................... 23
6 EVALUATION ........................................................................................ 25
6.1 First Prototype ................................................................................ 25
6.2 Second Prototype ........................................................................... 26
6.3 Third Prototype ............................................................................... 28
6.4 Final Prototype ............................................................................... 30
7 RECOMMENDATIONS .......................................................................... 32
8 CONCLUSION ............................. ERROR! BOOKMARK NOT DEFINED.
REFERENCES .............................................................................................. 33
APPENDIX A – PROJECT SPECIFICATION ............................................... 35
4
1 INTRODUCTION
1.1 Cover in Games
“More than anything else in the past ten years, there is one single-player
gameplay mechanic that has done more to revolutionize video games. That
mechanic is cover” [Ashcraft, 2010].
A cover system is a gameplay mechanic
which allows game characters to take
advantage of the environment in order to
avoid enemy fire and detection. It is mostly
used in first and third person shooters as well
as in stealth-action games. The concept of
cover appeared quite early on, with games
such as Space Invaders created in 1997,
allowing the player to stay briefly out of
enemy fire using destructible barriers (cf.
figure 1). However, proper cover systems
weren’t implemented as part of gameplay until 1995, with Time Crisis (cf.
figure 2), a first person shooting arcade game which allowed the player to
hide behind objects when pressing a pedal.
Figure 1: Space Invaders
Screenshot
Figure 2: Time Crisis Screenshots
5
More games started using this as well, and later inspired the cover system of
Gears of Wars, whose success made cover mechanisms practically a
requirement of first and third person shooters developed afterwards.
1.2 Problem Overview
With players allowed to take advantage of cover, non-playable characters
(aka NPCs) need to be able to use this feature as well, in order to interact with
the game environment in a natural and human-like way.
Failing to do so will break the player’s immersion in the game, removing the
illusion that he is playing against intelligent enemies, capable of the same
game awareness as any other human player.
This report will focus on the navigational aspect of the problem and choose to
ignore the decision making component. It will look at different world
discretization and pathfinding algorithms used to navigate an agent as well as
how games incorporate cover in their AI. Based on the research done, a
framework will be presented implementing pathfinding techniques based on
the AStar algorithm which will take advantage of cover.
1.3 Requirements
In order to provide a solution to the previously stated problem, the following
list of requirements must be achieved:
Project objectives include :
getting AI characters to follow a given path
implementing heuristic pathfinding taking cover points into account
allowing user input to change AI position and destination
Personal objectives include :
learning how to use and program for Unity
gaining a better knowledge of environment discretization
learning about and implementing pathfinding algorithms
6
2 METHODOLOGY
2.1 Unity
The framework was developed using Unity, a free game development tool
used to create 3D games for different platforms. It is made up of an editor
allowing users to easily change game content through a visual interface, and
an engine which executes the actual game. It is component based and
supports different scripting languages as well as C#.
Unity was chosen as it allows to quickly display results in 3D as well as 2D,
without having to spend time implementing a graphical interface. At the start
of the project, Unity didn't have pathfinding integrated into it yet (unlike other
engines such as the Unreal Development Kit) which allowed the creation of a
pathfinding system from scratch. However, the next release of Unity (version
3.5) will handle automatic navigation mesh generation and pathfinding. The
beta version has already been released and is available for testing [Unity
Technologies, 2012].
2.2 Evolutionary prototyping
“Evolutionary prototyping is a lifecycle model in which the system is
developed in increments so that it can readily be modified in response to end-
user and customer feedback” [CxOne, 2002]. It was chosen for this project as
the exact requirements and design of the final product were vague as they
relied on research and an understanding of Unity which wasn’t present at the
start of the project. Evolutionary prototyping allows the requirements of the
product to be redefined in response to user testing and gained knowledge.
The project was divided into several phases or stages, focusing on different
aspects of the problem. Initially, three phases were defined, where the first
phase implemented environment representation, including cover, the second
pathfinding and the third user input. This was changed so that the first phase
no longer tried to integrate cover in the environment and instead let the third
phase focus solely on cover, both with the environment and pathfinder. A
7
fourth stage was added which allowed for user input to change runtime
variables, as previously done in the third phase. For each phase, the basic
requirements for the prototype were defined and then developed.
Once done, the prototypes were tested and depending on whether or not they
met the set requirements, the specifications were changed to allow for new
features or to remove bugs and design flaws. The process was then repeated
until a satisfying result was achieved. Each stage and its prototype are
described in further details in the evaluation section of this paper.
Stage 1
o Simple level with obstacles
o Actor can move to mouse click
o Waypoints connected to one another
Stage 2
o Implementation of A* algorithm
o Actor can ask pathfinder for path
o Actor avoids obstacles
Stage 3
o Creation of cover points
o Pathfinding can take cover into account
o Debug shows multiple paths
Stage 4
o Actor and enemies can be dragged across scene
o Enemy position
influence cover validity
Figure 3: Stages of development
8
2.3 Testing
The testing of prototypes was done in two different ways. The first consisted
in running the application multiple times with different scenarios to check for
inconsistencies or implementations flaws. This method mostly helped finding
bugs and removing unwanted behaviours. Once this was done, prototypes
would be given to users to be informally tested in the university labs. A brief
explanation of the project was given before letting the user experiment with
the framework. All of the testers had prior knowledge of unity and therefore
had no problems with the concept of gizmos, prefabs and inspectors which
were used in the editor. Testers mostly played around in the editor by adding
waypoints and covers before briefly testing it. At the end of each session,
testers would be asked if any improvements should be made to the
framework. Whenever possible the answers would be taken into account in
order to refine the requirements of each prototype. This kind of testing often
led to additional features being added, most of them editor and debugging
oriented. A total of seven students took part in these tests, three of which
tested every prototype created during the project.
9
3 RESEARCH
In order to develop the AI navigation system, different types of environment
representations and pathfinding algorithms were researched as well as their
implementations.
The research on environment representation will mainly focus on grids,
waypoints and navigation meshes. It will look at each technique’s pros and
cons in order to select the most suitable one for the project. Environment
representation isn’t the focus of this project and therefore it will not be
automatically generated but manually inserted by the user.
The pathfinding research is going to be more expansive as it will explore
different pathfinding algorithms and ways to expand them, trajectory
smoothing and heuristic constraints.
3.1 Pathfinding in Unity
As mentioned in the methodology section, the version of Unity used for this
project (3.42) does not have pathfinding integrated into it. However, some
users have provided packages and scripts implementing pathfinding for other
users to use in their own projects.
AngryAnt’s path project is available on Unity's assets store and is free to use
as well as extensively documented. It allows the user to create waypoints and
link them together in the editor using the Navigation inspector [Johansen,
2011].
Arongranberg's A* Pathfinding Project is also available on the asset store and
consists of two versions, including a free one. This project is more extensive
than AngryAnt's as it includes a lot more features. These include automatic
navmesh (aka navigation mesh) generation, handling of many different graph
types, use of path modifiers and support of various heuristics [Granberg,
2011].
10
Figure 4: Arongranberg's A* Pathfinding Project [Granberg, 2011]
UnifyWiki, the wiki for unity related scripts, shaders and tutorials also has a
few examples of pathfinding scripts, including AStarHelper and
WaypointMaster. Those scripts are pretty simple and while they provide an
understanding of pathfinding, they do not however provide in-editor
functionalities like the packages mentioned above [Unify Community, 2012].
3.2 World Discretization
In order to search a game environment the pathfinding algorithm needs a
simplified representation of the game world in terms of navigation data that
can be stored and searched through. “Fundamentally, all search spaces are
graphs: they all consist of some number of atomic unit units of navigation, or
nodes, and some number of connections, or edges, between pair of nodes”
[Tozour, 2003].
This section will discuss the data representation needed by the algorithm to
understand the game environment and will describe three commonly used
techniques in games: grids, waypoints graphs and navigation meshes.
However, a lot of other methods exist such as quadtrees, corner graphs,
volumes, etc...
3.2.1 Grids
“The simplest way to represent a search space is with a regular grid of
squares, rectangles, hexagons, or triangles” [Tozour, 2003]. The grid is
placed on top of the environment, dividing it in cells which are flagged as
11
navigable or not. Figure 5 shows the same environment with a. using a
square grid representation and b. a hexagonal representation. Navigable
nodes can be seen in white and non-navigable in grey.
Figure 5: Grid Graph [Tozour, 2003]
The number of neighbours a node can have depends on the type of the node
and affect the way an agent will be able to move in the level (cf. Figure 6).
Those are the key points to be taken into account when looking at
implementing a grid based graph:
o Popular in 2D strategy games with top down perspective, but can also
be used for 3D with a few modifications added
o Requires huge amount of cells to provide accuracy (slows down
pathfinding and has a bigger memory footprint)
o Has difficulties with entities with different shape and movement
capabilities
o Can be recalculated easily when environment changes
Figure 6: Grid movements
12
3.2.2 Waypoints
“Waypoint graphs tend to be very popular with 3D games, as they generally
handle 3D game worlds quite easily. Because you can place a waypoint at
any point in 3D space, you can use waypoint graphs very easily for navigating
outdoor terrain or three-dimensional game worlds” [Tozour, 2003].
Figure 7: Waypoint Graph [Tozour, 2003]
Those are the key points to be taken into account when looking at
implementing a waypoint graph:
o Works well in human architectures such as corridors and tight spaces
(areas which constrain character’s movement to straight lines)
o Not realistic in large rooms and open areas, since they introduce
artificial limitations that do not exist in the game world
o Usually requires hand tuning by level designers, however can be
computed automatically from geometry
o Higher quality graphs with better accuracy/realism are achieved by
adding more and more nodes which increases memory footprint and
slows down pathfinding
o Has difficulties with entities with different shape and movement
capabilities
o Does not deal gracefully with environment changes at run-time.
13
3.2.3 Navigation Meshes
“A navigation mesh is a representation that covers the walkable surfaces of
the world with convex polygons” [Tozour, 2003]. They are created from the
polygonal representation of the environment, usually using the ground plane.
Figure 8 shows two different types of navigation meshes: a) triangle based
and b) N-sided-poly based. N-sided-poly based meshes give a better
representation of search space and allow the pathfinding to run faster as it
has a smaller memory footprint than triangle-based navigation mesh.
However, they tend to make agent movement stick too closely to walls and
game geometry.
Figure 8: Navigation Mesh Graph [Tozour, 2003]
Those are the key points to be taken into account when looking at
implementing a navigation mesh graph:
o Allows for optimal path for entities with different shape and movement
capabilities
o Can handle both small indoor areas as well as large outdoor
environments
o Requires storage of high number of polygons when geometry is
complex
o Guarantee that an entity can freely walk from any point within a
polygon to any other point within that same polygon
o Can be automatically generated from geometry or created manually
o Does not need to store obstacles
14
3.3 Pathfinding algorithm
Pathfinding is a technique used to find the path of an agent between two
points in an environment where the path is defined as a list of points or nodes.
Dijkstra's algorithm is a classic algorithm for traversing graphs with edges of
differing weights. It begins by looking at the start node, stores all its
neighbours in a list and evaluates those closest to the start node first. The
algorithm takes a path’s length or cost into account but ignores the direction of
the goal [Stout, 1999].
Best-First-Search is similar to Dijkstra’s algorithm, except that instead of
nodes in the list being scored by their distance from the start, they are scored
by an estimate of the distance remaining to the goal [Stout, 1999].
AStar takes the best of both algorithms by evaluating the node in the list
based on both the cost of the node in relation to the starting node and the
estimate of the distance left to reach the goal.
3.3.1 AStar
AStar is one of the best established algorithms when searching for an optimal
path as it is simple to use while still highly efficient. It is not as fast as some
pathfinding algorithms but it guarantees to find the cheapest path if the goal
can be reached. It uses a heuristic to project the path in the right direction by
looking at nodes with a higher probability of leading to the goal, therefore
avoiding searching the whole graph and making the algorithm faster.
The algorithm contains two lists of nodes, commonly referred to as the open
and closed list. The closed list stores the nodes which it has already explored
while the open list contains the nodes which are waiting to be evaluated.
Every node in the graph stores a cost and heuristic value which is accessed
by the algorithm when deciding which node to explore next from the open list.
15
The chosen node is the one with the lowest score f(n) = g(n) + h(n)
where:
f(n) is the score assigned to node n,
g(n) is the actual cheapest cost of arriving at n from start node,
h(n) is the heuristic estimate of the cost to the goal from n [Stout, 1999].
The following figure (cf. figure 9) demonstrates the basic structure of the
AStar algorithm in pseudo code.
Figure 9: AStar Pseudo Code [Game Garden, 2006]
The cost of a node is calculated by adding up the cost of all the nodes which
had to be traversed from the start to reach the current node. The estimate, or
heuristic, is usually calculated by multiplying the distance between the node
and the goal with the minimum node cost. Figure 10 provides functionalities
for calculating the heuristic of a node and the cost from one node to another,
where movement cost is calculated both by the distance and speed allowed
by the terrain.
16
Figure 10: Cost Function and Heuristic [Sterren, 2002]
3.3.2 Heuristics
The heuristic function has a lot of influence on the pathfinding algorithm and
can be used to control AStar’s behaviour.
If the heuristic, h(n), is equal to zero, then only the node’s cost, g(n), plays a
role, and AStar becomes equivalent to Dijkstra’s algorithm. If it is always lower
or equal to the cost of moving from the current node to the goal, then the
shortest path will be found. However, the lower the heuristic, the more nodes
are examined by the algorithm and the more time it takes to find the goal. If
the heuristic is equal to the cost of moving from the current node to the goal
node, then the AStar algorithm will perform best as it will only select nodes
that are on the cheapest path. However, this is a best case scenario and is
rarely achievable. If the heuristic is slightly greater than the cost of moving
from the current node to the goal, the algorithm will run much faster, however
the path found may not be the shortest or cheapest. The higher the heuristic
17
is compared to the cost, the more it resembles Best-First-Search [Patel,
2010].
3.3.3 Tactical Pathfinding
“In cost functions for conventional (shortest path) path-finding, the costs for a
move from one position to another solely consist of the corresponding travel
costs. Such a cost function can easily be extended to invoke a position
evaluation function for each of the positions visited. This position evaluation
function can, for example, add costs to make it more expansive (and less
attractive) to cross the player’s line-of-fire or to be visible to hostile guards”
[Straatman, 2005].
Figure 11: Examples of position evaluation [Straatman, 2005]
In the previous section, figure 10 showed an example of a cost function to
help determine the shortest path available. Figure 12 provides a revised
function which looks at both travel time and location risk in order to calculate
the cost between two nodes.
18
Figure 12: Tactical Cost Function [Sterren, 2002]
By simply adding cost to locations which are not considered tactically sound,
the obtained path can demonstrate a higher degree of understanding of the
environment.
Figure 13: Shortest Path VS Tactical Path [Sterren, 2002]
Figure 13 demonstrates two different path calculate in the same environment,
with a) having used cost and heuristic functions solely based on travel time
while b) implemented the function from figure 12.
19
4 DESIGN
This section will look at the different components that make up the application
and briefly explain why they were used. The following diagram (cf. figure 3)
presents a simplified overview of the application.
Figure 14: System Overview
The actor (a) is a game agent which can navigate the level by following a
path. An actor can have multiple paths but can only follow one at a time. In
order to get a path, the actor must query the pathfinder (b) and give it its
current location, the desired goal and a navigation point visitor (c). Whenever
the user clicks on the scene, the desired location is set to the mouse position
and the actor asks the pathfinder for two paths, one using Basic AStar (c)
which can be seen on the scene as the red line, and the other using Cover
AStar (c), which is drawn in green.
The pathfinder (b) is a component made up of a pathfinding algorithm and
navigation data, aka world discretization, constituting of cover points (f),
20
waypoints (e) and the connections between them. The pathfinding algorithm
implements AStar but uses the navigation point visitor (c) given by the actor
as a parameter to calculate the cost and heuristic of navigation points, and to
determine the best navigation point available. The pathfinding component has
its own inspector accessible in the editor (cf. figure 4) which allows the user to
assign values to pathfinding variables, such as the influence cover points
should have compared to waypoints and the maximum distance allowed
between two connected points. The inspector also has two buttons which
allow the user to create or clear the connections between navigation points
while still in the editor.
Figure 15: Editor
Navigation point visitor (c) is an interface implemented by Basic AStar and
Cover AStar which provides functions for calculating the cost and heuristic of
a navigation point. Basic AStar calculates those according to distance while
Cover AStar takes into account both distance and the weight of the point,
making cover points cost less than waypoints. Navigation point visitor also
provides a function which determines the best navigation point from a given
lists. Both Basic AStar and Cover AStar define the best point as the one with
lowest cost and heuristic. However if new classes were to inherit from
21
navigation point visitor, it could decide the best point to be the cover point with
the lowest cost calculated according to distance, allowing for different
behaviours.
The cover manager (d) is in charge of updating the costs of cover points (f).
Whenever a new path needs to be calculated, it checks every enemy (g) in
the level to see if it has moved and updates cover points accordingly. If an
enemy can see a cover point, its cost is set to neutral and it is represented as
a red box when in debug.
Waypoints (e) are manually added to the level by the user in editor mode by
dragging the waypoint prefab into the scene. Once placed, they can be
connected to each other and cover points using the pathfinder’s inspector (b).
This provides a network of nodes which is used by the pathfinding component
(b) to create paths.
Cover points (f) work in the same way as waypoints (e) as they are also
placed manually using prefabs. Unlike waypoints however, they don’t only
consist of a position but of an area in space which can be disabled or enabled
by the cover manager (d). When disabled, the cover point acts like a
waypoint.
4.1 World Discretization
“With a large number of designers creating a large number of world pieces, a
design team can end up wasting a lot of time adding path points just to allow
the AI to navigate the game world properly. An automated solution also allows
you to solve the problem just once, rather than having to address it in every
part of the game world separately” [Tozour, 2003]. However, taking into
account the scope of this project, an automated solution would have required
too much time. Therefore, navigation points will have to be added manually to
every scene as this solution is simpler to implement. This works well for cover
points as “manual placement is a great way to fine tune the behaviours by
placing cover locations exactly where you want them. So if you have special
geometry, or need to customize the cover location per level to fit in with a
22
story, then manually adding cover locations to the level is ideal”
[Champandard, 2007]. Cover points can also easily be attached to game
objects as prefabs to make level creation faster.
23
5 IMPLEMENTATION
5.1 World Discretization
Waypoints and cover points are created using the waypoint and coverpoint
script respectively, both of which inherit from the navigationpoint script. This
script handles most of functions needed to provide data to the pathfinding
component. These include storing the node’s cost, heuristic and parent as
well as keeping track of all the connections available to other navigation
points.
The waypoint and coverpoint script are only interested in providing a visual
representation to the user through the use of gizmos, and therefore implement
the OnDrawGizmos function. The following code sample is used to represent
waypoints and their connections.
Unlike waypoints, cover points are more than just points as they represent
areas in the level. The user should be able to rotate and scale them however
he sees fit. However, gizmos don’t automatically rotate and scale with the
object transform (cf. Figure 16).
24
The code shown below draws a cube that has the same characteristics as its
actual object and that can be manipulated. This is done by setting the gizmos
matrix to the object’s world matrix [Wong, 2011].
25
6 EVALUATION
This section will examine the development of the framework step by step by
looking at each prototype. It will talk about the problems encountered and
explain what measures were put in place to provide the solution which led to
the final product.
6.1 First Prototype
The aim of the first prototype was to provide a basic environment which could
be used as a test bed. The level consisted of an agent represented by a
yellow rectangle, a floor, a few obstacles represented as green rectangles and
a camera allowing the user to view the scene (cf. figure 3).
Figure 16: In Editor Level
Three more scripts were created at this stage to allow the user to place
waypoints on the level while in the editor. The first script, Waypoint,
implements gizmos and connects to other waypoints if those are in range and
an actor can walk from one waypoint to another without encountering any
obstacles.
26
Figure 17: In Editor Waypoints
Gizmos are used to display game debug information, both in the editor and at
runtime. They can easily be enabled or disabled at any time, however they
are not available in release mode. The
Waypoint script uses them to represent
waypoints as blue spheres and connections
as green lines, as can be seen in figure 4.
The two other scripts, PathfinderScript and
PathfinderEditor were created to handle
pathfinding. As the actual implementation of
a pathfinding system wasn’t required for this
prototype, PathfinderScript simply finds all
the waypoints objects in the level and
connects them to each other. PathfinderEditor is used to customise the
Pathfinder object’s inpector (cf. figure 5) in order to allow the user to connect
waypoints while still in the editor, by simply clicking on a button.
6.2 Second Prototype
The goal of the second prototype consisted in implementing a pathfinding
algorithm. It builds on the previous prototype by altering existing scripts to
allow the game actor to access the pathfinding component and ask for a path
to follow.
Figure 18: Pathfinder Inspector
27
Figure 19: Actor Navigation Progression
The AStar pathfinding algorithm was implemented as part of PathfinderScript,
and a function was created to allow the actor to query a path. The Waypoint
script was changed to allow access of the variables needed by the AStar
algorithm, such as the cost and heuristic values of the waypoint. Figure 6
shows a small video demonstrating the actor navigating the environment while
avoiding obstacles. At this point, only distance is being taken in account by
the pathfinding algorithm, and as such, the actor is following the shortest path
available.
During the testing phase of this prototype, it was discovered that at times the
actor would move awkwardly instead of following what the user would assume
to be the shortest path. The reason for this is that the pathfinding algorithm
would be given the start and goal points of the actor, find the closest waypoint
to these positions and calculate the shortest path from one waypoint to the
other (cf. figure 7). This was solved by having the pathfinding algorithm create
temporary waypoints at the given start and goal positions and calculate the
path from these instead (cf. figure 8).
28
In order to find out what caused the problem, debugging was done using the
existing waypoint gizmos which rendered the scene quite cluttered. This led to
the decision of disabling waypoint gizmos at run-time and allowing the actor to
draw the path to follow. A new script call path was created which stored the
list of waypoints. It includes a function which returns the next position the
actor should move to and a function to check if the path is finished. It also
includes debugging functionalities which allows the actor to draw lines
representing the path and to choose which colour to draw those lines with.
6.3 Third Prototype
The aim of the third prototype was to incorporate cover into the framework.
Once again, this prototype was based on the work done in the previous
prototypes. Cover was added to the environment as a white wired box which
can be manually placed in the level (cf. figure 9). It is made up of the
Coverpoint script which acts similarly to the Waypoint script, as they can both
generate connections to each other and be used by the pathfinding
component to make up a path. In order to avoid duplicated code and allow the
user to be able to continue adding similar classes in the future without having
to change any of the pathfinding scripts, a script NavigationPoint was created.
It is inherited by both Coverpoint and Waypoint. NavigationPoint implements
all the functionalities required for pathfinding which used to be in Waypoint. As
such, Coverpoint and Waypoint only take care of drawing themselves at this
point in the project. Two red boxes representing enemies were also added to
Figure 21: Using closest waypoint Figure 20: Creating new waypoint
29
the level. For the time being, they only exist for decorating purposes as they
do not implement scripts, or affect other scene components in any way.
Figure 22: In Editor Cover
With cover part of the environment, the pathfinding component can now
favour paths that contain more cover than others. This was done by adding a
cost to all navigation points which are not considered as cover. In order to do
this, three new scripts were created, INavigationPointVisitor, DistanceVisitor
and CoverVisitor. The first script, INavigationPointVisitor, is an abstract class
which cannot be instantiated and whose role is to provide a set of functions to
be implemented in inherited classes DistanceVisitor and CoverVisitor. The
functions in charge of calculating cost and heuristic values of a navigation
point were part of the pathfinding component but were removed and put in
DistanceVisitor and CoverVisitor instead. DistanceVisitor calculates the cost
of each navigation point, only taking into account the distance between those
points while CoverVisitor adds the cost related to cover. When calling the
pathfinding component, the actor now needs to add an INavigationPointVisitor
argument which will tell the pathfinding algorithm how to calculate the cost
and heuristic. Figure 10 displays screenshots of different tests done,
demonstrating the differences between the two heuristic used. The red line
shows the shortest path, calculated with DistanceVisitor, while the green line
shows the path favouring cover, calculated with CoverVisitor.
30
Figure 23: Distance vs. Cover Heuristic
The technique is not entirely accurate but it can easily be fine-tuned to fit in
with the current level by adding or removing weight on the non-cover
navigation points. This prototype fails to take into account the position of
enemies in relation to covers. On top of that, while testing the framework
users did not like that cover location had to be pre-calculates, and would have
preferred having cover surrounding the obstacle and have the simulation
decide at run-time whether the cover is acceptable or not. As enemy-cover
line of sigh was part of the requirements of the next prototype, those issues
were solved in the next section.
6.4 Final Prototype
The first requirement of this prototype was to allow enemy line of sight to
affect the validity of cover. A CoverManager script was created for this
purpose. The script finds all the cover points and enemies in the scene and
then checks every cover at run-time to see whether it can be seen from where
an enemy is standing. If the cover isn’t valid, its cost is set to equal that of a
normal waypoint. CoverManager also implements debugging functionalities
which displays available cover in red when enabling gizmos (cf. figure 11).
31
Figure 24: Run-time Cover Debug
The second requirement of this prototype was user input. With this in mind, a
drag script was created and added to the actor and enemy objects, allowing
the user to move them around the scene. A new variable was also created
which allowed the user to decide
the influence cover should have
on the pathfinding algorithm. The
pathfinder’s inspector (cf. figure
12) was altered to make that
variable accessible and was also
given a new button to clear the
navigation network, as it was
suggested during testing by
several users. Finally, a map was chosen from the first person shooter game
Call of Duty and replicated in order to be able to test the framework in a more
complex environment.
Figure 25: Pathfinder Inspector
32
7 RECOMMENDATIONS
The solution provided in this paper contains several flaws which were not
addressed. The pathfinding component doesn’t have the means to
differentiate long and short exposures to enemy fire, nor does it take into
account the movement of enemies while following a path. Some techniques to
overcome this are offered in [Sterren, 2002] as well a method to lower CPU
time spent on ray casting tests which are done when checking whether a
cover is valid or not. A similar technique addressing the same issue is given in
the form of a line-of-sight lookup table in [Straatman, 2005].
33
REFERENCES
Ashcraft, Brian. 2010. How Cover Shaped Gaming’s Last Decade. In Kotaku.
Available online at http://kotaku.com/5452654/how-cover-shaped-gamings-
last-decade. Accessed 03 May 2012.
Champandard, Alex J. 2007. Strategies for Implementing Cover Behaviors.
Available online at http://aigamedev.com/open/article/cover-strategies/.
Accessed 03 May 2012.
CxOne. 2002. Evolutionary Prototyping. Available online at
http://www.construx.com/File.ashx?cid=814. Accessed 03 May 2012.
Game Gardens. 2006. Path Finding Tutorial. Available online at http://www-
cs-students.stanford.edu/~amitp/gameprog.html. Accessed 03 May 2012.
Granberg, Aron. 2011. A* Pathfinding Project. Available online at
http://www.arongranberg.com/unity/a-pathfinding. Accessed 03 May 2012.
Johansen, Emil. 2011. Path. Available online at http://angryant.com.
Accessed 03 May 2012.
Patel, Amit J. 2010. Amit’s Thoughts on Pathfinding. Available online at
http://wiki.gamegardens.com/Path_Finding_Tutorial. Accessed 03 May 2012.
van der Sterren, William. 2002. Tactical Pathfinding with A*. In Game
Programming Gems 3, Charles River Media.
Stout, Bryan. 1999. Smart Move: Intelligent Path-Finding. In Gamasutra.
Available online at
http://www.gamasutra.com/view/feature/131724/smart_move_intelligent_.php
?print=1. Accessed 03 May 2012.
34
Straatman, Remco. 2005. Killzone’s AI: Dynamic Procedural Tactics. Guerrilla
Games. Available online at
http://www.cgf-ai.com/docs/straatman_remco_killzone_ai.pdf. Accessed 03
May 2012.
Time Crisis. In Arcade History. Available online at http://www.arcade-
history.com/?n=time-crisis&page=detail&id=2903. Accessed 03 May 2012.
Tozour, P. 2003. Search space representations. In AI Game Programming
Wisdom 2, 85-102. Charles River Media.
Unify Community. 2012. Unify Community Wiki. Available online at h
http://unifycommunity.com/wiki/index.php?title=Main_Page. Accessed 03 May
2012.
Unity Technologies. 2012. Unity Game Engine. Available online at
http://unity3d.com. Accessed 03 May 2012.
Wong, Nicholas. 2011. How to rotate gizmos to fit a game object in Unity.
Available online at http://nicholasworkshop.com/2011/11/28/how-to-rotate-
gizmos-to-fit-a-game-object-in-unity. Accessed 03 May 2012.
35
APPENDIX A – PROJECT SPECIFICATION
Working Title
Cover-based pathfinding
Overview
The objective of this project is to develop a pathfinding algorithm derived from
A Star that will take into account cover points. The algorithm will be
demonstrated on the 3d game engine Unity.
Problem
Most of today’s FPS-like games now implement a cover system accessible for
both the AI and player. In order for the AI to look as “intelligent” and human-
like as possible, it should take full advantage of the given cover system when
navigating the game environment. This means that instead of always taking
the shortest route to its goal, an AI agent should be able to take the shortest
route with the most cover points providing it with protection in order to reach
its goal.
Research
In order to develop the AI navigation system, I will research different types of
environment representations and pathfinding algorithms as well as their
implementations.
The research on environment representation will mainly focus on grids,
pathNodes and Navmeshes. It will look at each technique’s pros and cons in
order to select the one most suitable for the project. Environment
representation isn’t the focus of this project and therefore it will not be
automatically generated but manually inserted by the user.
The pathfinding research is going to be more expansive as it will explore
different pathfinding algorithms and ways to expand them, trajectory
smoothing and multiple heuristic constraints.
Methodology
I will use evolutionary prototyping for my methodology. My project will be
divided into phases focusing on different aspects of the problem, which will be
36
prototyped one after the other, each one building on top of the previous
version. The first phase will focus on implementing environment
representation, the second will use it to implement pathfinding and the third
will allow for user input to change runtime variables.
For each phase, I will first identify the basic requirements for the prototype
and then develop it. Once done, I will test the prototype and depending on
whether or not it meets the requirements set, change the specifications and
prototype. If I am satisfied with my prototype, I will keep as a base for the
next prototype.
Objectives
Personal objectives include:
learning how to use and program for Unity
gaining a better knowledge of environment discretization
learning about and implementing pathfinding algorithms
Project objectives include:
getting AI characters to follow a given path
implementing heuristic pathfinding taking cover points into account
allowing user input to change AI position and destination
Schedule
The following schedule stands as an approximation of the tasks that should
be carried out each month. Those tasks may be subject to change as the
project develops.
December
Research pathfinding algorithms
Research, compare and document world discretization techniques
Decide on a world discretization technique
Draft paper introduction
Draft paper research on discretization techniques
Get basic AI following a path in Unity
January
Research, compare and document pathfinding algorithms
Implement basic pathfinding techniques in Unity
Test pathfinding techniques in Unity
Draft paper design and implementation
37
February
Research and document heuristics in pathfinding
Implement pathfinding using cover heuristics in Unity
Test pathfinding using cover heuristics in Unity
Continue to draft paper design and implementation
March
Implement user input
Test code and different variables
Continue to draft paper design and implementation
April
Finish paper