Path Following
Seth Hendrick

Link to Demo:

Space bar: Go to an overhead view
Left/Right arrow: Move the camera to the next guy.  The camera can not be overhead, or pressing these buttons does nothing.

The 75 guys first spawn at random spots in the map.  They can initially appear in the water, or over a mountain, or off the path.  Once spawned, however, they will make their way to the path.  Once on the path, they will follow it forever while trying not to get in the other guys' path.  There are 24 waypoints

Implementation notes:
A Path class contains all the way-points on the path.  A single instance of Path lives inside of GameManger, the main class.  

WayPoints contain a gameObject to something on the map; in this case, an invisible, intangible cylinder.  Way-Points also contain the distance to the next way point, a vector to the next way-point, and a normalized vector to the next way-point.  The reason why Way-points contain those values is because they will never ever change.  Therefore, they are calculated once, and then live in memory for the program, instead of being calculated each frame, which is expensive.  All of those values get set when the setNextWayPoint method is called, and are accessible through getters.

The SteeringVehicle class is like other assignments.  It calculates the steering force each frame, and applies it.  What is new in this assignment is that each vehicle has an ID associated with it.  This way, it is easier to pick the vehicles out of an Array or List.  Their maximum speed can also vary by +/- 20 what is given in SteeringAttributes.

The GameManager class is the main class.  It detects the location of the way-points by finding all game objects with the name "WPX", where X is the id number.  It will then add the way-points to the path object in the correct order.  The GameManager also creates all the guys by putting them in a random spot on the map.  Each frame, the GameManager class will create a look up table for the distances between all of the guys.  This way, the calculation is done once per frame, instead of many.  The only thing the guy needs to do is give its id, and the id of another guy, and the GameManger will return the distance without any calculation needed.  The GameManager is also in charge of moving the camera if the user wants to move it.  Depending on which arrow key the user presses, the GameManager will set the camera's target to the next or previous guy in the guy array.  If the user presses the space bar, the camera will switch to an overhead one.

The Steer class has a new method called follow.  It takes a path object as an argument.  If the vehicle that owns the steer object does not have a target, the follow algorithm iterates through all of the way-points to determine what the closest one is, otherwise, it only iterates through the nearest three.  What the algorithm does is that it has a number called "World record." that is set to the maximum floating point number.  The algorithm then iterates through the waypoints, and if the distance from a waypoint is less than the world record, the world record gets overwritten, and if the next waypoint's distance is even closesr, the world record gets overwritten again, etc.  Which ever waypoint is the closest, it becomes the target.  The distance is determined by first predicting where the vehicle will be in 5 frames by multiplying the unit vector of the velocity by 5 and adding it to the current position.  Then, the point orthogonal to the path from the predicted position is found, this is called the normal point.  If the normal point is not on the line segment between the two waypoints, it is assumed that the guy is at the end of the waypoint, and the direction the guy is supposed to travel becomes the vector between the next waypoint, and the waypoint after.  Otherwise, the direction is the vector to the next waypoint from the current one.  The distance the guy is away from the center is then calculated, and if it is less than the world record, it becomes the target.  The guy will only steer towards the center of the path if it is outside the path's range, or the guy is travelling too slow.  The reason why the the guy will seek the nearest path center when it is travelling too slow is because there would be a chance where a faster guy would get directly behind a slower guy, but remain perfectly inside the path.  The separation algorithm would then kick in, slowing the faster guy down, sometimes to a complete stop.  Since the guy was not outside the path range, it would not seek the path's center, and therefore would not move as other forces were not acting on it.