SlideShare a Scribd company logo
1 of 4
Nathaniel Baird
6/21/2016
Velo Write Up
While working on past projects, specifically TRIAD, I found the task of designing
intelligent AI intriguing and rewarding. One feature of this work that I felt most intimidated by
was path finding. Unity has a built in “nav-mesh” feature which I used for AI path finding in
both TRIAD and my zombie survival game. While working on these games I found myself
frustrated with the system on multiple occasions. While the benefits of a convenient, readymade
system were undeniable, characters would occasionally slide on the floor or rotate unpredictably.
I decided that it would be worthwhile to attempt to design a path finding system from the ground
up. I needed to start simple. Track cycling racing takes place on a banked oval called a
velodrome. Using my personal experience with track cycling I attempted to create a moderately
realistic simulation of the sort of behavior found in the sport. This behavior includes locating
oneself as close to the inside of the track as possible (as it is the shortest distance to the finish
line), passing other racers on their outside, drafting other racers to maintain one’s stamina and
avoiding physical contact with other racers.
Originally I planned to assign each racer a ring of nodes that expanded and retracted to
reflect their trajectory around the track. If the radius of one ring approximated the radius of
another the two racers would be in danger of colliding. The racer further back would expand its
ring, providing it a path around the outside of the racer in front. However I quickly realized that a
more efficient node-based method would involve generating several concentric rings, called
‘lanes’, which each racer would adhere to at any given moment. I opted for a total of 5 lanes. The
following is the code I used to generate lane 2, which is comprised of 94 nodes. 94 nodes turned
out to be the lowest amount required to properly execute the code responsible for determining
where racers are relative to their opponents (the space between each node is roughly 1 bike
length).
lane2 =new Vector3[94];
zVal =-8.75f;
upperCurveAdd =0;
lowerCurveAdd =0;
startX +=1;
for (int i =0; i <lane2.Length;i++)
{
if(i < 20)
{
zVal +=2.1875f;
lane2[i]= new Vector3(startX,0, zVal);
}
if(i >= 20 && i <35)
{
upperCurveAdd -=12f;
Vector3 dir =Vector3.Normalize(upperCurve.transform.position-lane2[19]);
dir.x *=-1;
dir =Quaternion.AngleAxis(upperCurveAdd,Vector3.up) *dir;
lane2[i]=upperCurve.transform.position+(dir *startX);
}
if(i >= 35 && i <67)
{
zVal -=2.1875f;
lane2[i]= new Vector3(-startX, 0, zVal);
}
if(i >= 67 && i <82)
{
lowerCurveAdd -=12f;
Vector3 dir =Vector3.Normalize(lowerCurve.transform.position -lane2[66]);
dir.x *=-1;
dir =Quaternion.AngleAxis(lowerCurveAdd,Vector3.up) *dir;
lane2[i]=lowerCurve.transform.position+(dir *startX);
}
if(i >= 82)
{
zVal +=2.1875f;
lane2[i]= new Vector3(startX,0, zVal);
}
}
The lane is entirely two-dimensional with no concern whatsoever for the y-value (or
height) of the nodes. Rather than worry about the geometry of a banked oval I established the y-
value of each racer by capturing the location of the track mesh below. The racer’s y-value, then,
equals the y-value at which a raycast intersects the track.
With this system in place racers were capable of traveling around the track in their
respective lanes. The next task was to create systems for determining when racers should adjust
their speed or change lanes.
A central game manager keeps track of every racer in an array. Periodically racers run
through the array and check the nodes and lanes that other racers occupy. The first component in
the check determines whether another racer in the same lane occupies a node slightly larger than
the one currently occupied by the racer (a node is occupied if it is the node which the racer is
currently traveling toward). If the racer determines that they are blocked it does a check on the
lane above. If the lane is clear the racer moves up for a pass, if it too is occupied the racer
decreases its speed until it matches the racer in front. If the racer is not blocked in front (or is
blocked by a racer going the same speed or faster) the racer checks the lane below, and if safe
transitions into it. The following is the code which checks to see if a racer has room to move up a
lane.
IEnumeratorCheckUp()
{
yield return new WaitForSeconds(timer);
bool front =false;
bool safe =true;
for (int i =0; i <racerCount; i++)//check ifraceris above
{
racerA=gameManager.GetComponent<RacerPositions>().racers[i];
if(racerA.GetComponent<TrackRingPathing>().lane ==GetComponent<TrackRingPathing>().lane+1)
{
if(racerA.GetComponent<TrackRingPathing>().nodeInArray >=currentNode&&
racerA.GetComponent<TrackRingPathing>().nodeInArray -1 <currentNode)
{
safe =false;
}
if(racerA.GetComponent<TrackRingPathing>().nodeInArray <=currentNode&&
racerA.GetComponent<TrackRingPathing>().nodeInArray +1 >currentNode)
{
safe =false;
}
}
}
if (safe ==true)
{
GetComponent<TrackRingPathing>().MoveUp();
}
StartCoroutine("Choose");
}
I then added additional conditions under which racers can adjust their speed. Racers are
initiated with randomly generated sprint and attack speeds which determine their maximum
speeds in different circumstances. I implemented a stamina value which decreases gradually so
long as the racer is not drafting another racer. If the stamina is low enough the racer’s speed
begins to decrease. This gives races an ebb and flow; racers which get an early lead stand a good
chance of falling behind later in the race. On the final lap racers accelerate towards their
sprinting value. This system added new potential for the racers to make “mistakes”. For example,
if a racer is not initially boxed in but then suddenly is they may not have enough time to slow
down and will crash into the racer in front of him. I did not consider these features undesirable,
since in track cycling (a sport in which racers have no breaks) these sorts of scenarios actually
occur.
The final task was to add a human racer into the pack. The player is not ‘on rails’ in the
same way the AIs are. I devised a script that checks with the game manager frequently and
approximates the lane and node the racer would be at if they were on rails. The result is a system
in which the AI rarely cuts into the player and is capable of drafting off of him. Occasionally the
AI will invade the player’s space slightly due to the overlap in time between the various script’s
cycles (occasionally a script will not approximate the player’s location soon enough for the racer
to react to being blocked). I consider this a fine side effect of my programming, and it is one I
could easily tighten up by speeding up the rate of processing. But bike racing is a messy sport
and racers make mistakes, so I left it as it currently is.

More Related Content

Featured

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by HubspotMarius Sescu
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTExpeed Software
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 

Featured (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

Velo Write Up

  • 1. Nathaniel Baird 6/21/2016 Velo Write Up While working on past projects, specifically TRIAD, I found the task of designing intelligent AI intriguing and rewarding. One feature of this work that I felt most intimidated by was path finding. Unity has a built in “nav-mesh” feature which I used for AI path finding in both TRIAD and my zombie survival game. While working on these games I found myself frustrated with the system on multiple occasions. While the benefits of a convenient, readymade system were undeniable, characters would occasionally slide on the floor or rotate unpredictably. I decided that it would be worthwhile to attempt to design a path finding system from the ground up. I needed to start simple. Track cycling racing takes place on a banked oval called a velodrome. Using my personal experience with track cycling I attempted to create a moderately realistic simulation of the sort of behavior found in the sport. This behavior includes locating oneself as close to the inside of the track as possible (as it is the shortest distance to the finish line), passing other racers on their outside, drafting other racers to maintain one’s stamina and avoiding physical contact with other racers. Originally I planned to assign each racer a ring of nodes that expanded and retracted to reflect their trajectory around the track. If the radius of one ring approximated the radius of another the two racers would be in danger of colliding. The racer further back would expand its ring, providing it a path around the outside of the racer in front. However I quickly realized that a more efficient node-based method would involve generating several concentric rings, called ‘lanes’, which each racer would adhere to at any given moment. I opted for a total of 5 lanes. The following is the code I used to generate lane 2, which is comprised of 94 nodes. 94 nodes turned
  • 2. out to be the lowest amount required to properly execute the code responsible for determining where racers are relative to their opponents (the space between each node is roughly 1 bike length). lane2 =new Vector3[94]; zVal =-8.75f; upperCurveAdd =0; lowerCurveAdd =0; startX +=1; for (int i =0; i <lane2.Length;i++) { if(i < 20) { zVal +=2.1875f; lane2[i]= new Vector3(startX,0, zVal); } if(i >= 20 && i <35) { upperCurveAdd -=12f; Vector3 dir =Vector3.Normalize(upperCurve.transform.position-lane2[19]); dir.x *=-1; dir =Quaternion.AngleAxis(upperCurveAdd,Vector3.up) *dir; lane2[i]=upperCurve.transform.position+(dir *startX); } if(i >= 35 && i <67) { zVal -=2.1875f; lane2[i]= new Vector3(-startX, 0, zVal); } if(i >= 67 && i <82) { lowerCurveAdd -=12f; Vector3 dir =Vector3.Normalize(lowerCurve.transform.position -lane2[66]); dir.x *=-1; dir =Quaternion.AngleAxis(lowerCurveAdd,Vector3.up) *dir; lane2[i]=lowerCurve.transform.position+(dir *startX); } if(i >= 82) { zVal +=2.1875f; lane2[i]= new Vector3(startX,0, zVal); } } The lane is entirely two-dimensional with no concern whatsoever for the y-value (or height) of the nodes. Rather than worry about the geometry of a banked oval I established the y- value of each racer by capturing the location of the track mesh below. The racer’s y-value, then, equals the y-value at which a raycast intersects the track.
  • 3. With this system in place racers were capable of traveling around the track in their respective lanes. The next task was to create systems for determining when racers should adjust their speed or change lanes. A central game manager keeps track of every racer in an array. Periodically racers run through the array and check the nodes and lanes that other racers occupy. The first component in the check determines whether another racer in the same lane occupies a node slightly larger than the one currently occupied by the racer (a node is occupied if it is the node which the racer is currently traveling toward). If the racer determines that they are blocked it does a check on the lane above. If the lane is clear the racer moves up for a pass, if it too is occupied the racer decreases its speed until it matches the racer in front. If the racer is not blocked in front (or is blocked by a racer going the same speed or faster) the racer checks the lane below, and if safe transitions into it. The following is the code which checks to see if a racer has room to move up a lane. IEnumeratorCheckUp() { yield return new WaitForSeconds(timer); bool front =false; bool safe =true; for (int i =0; i <racerCount; i++)//check ifraceris above { racerA=gameManager.GetComponent<RacerPositions>().racers[i]; if(racerA.GetComponent<TrackRingPathing>().lane ==GetComponent<TrackRingPathing>().lane+1) { if(racerA.GetComponent<TrackRingPathing>().nodeInArray >=currentNode&& racerA.GetComponent<TrackRingPathing>().nodeInArray -1 <currentNode) { safe =false; } if(racerA.GetComponent<TrackRingPathing>().nodeInArray <=currentNode&& racerA.GetComponent<TrackRingPathing>().nodeInArray +1 >currentNode) { safe =false; } } } if (safe ==true) { GetComponent<TrackRingPathing>().MoveUp(); }
  • 4. StartCoroutine("Choose"); } I then added additional conditions under which racers can adjust their speed. Racers are initiated with randomly generated sprint and attack speeds which determine their maximum speeds in different circumstances. I implemented a stamina value which decreases gradually so long as the racer is not drafting another racer. If the stamina is low enough the racer’s speed begins to decrease. This gives races an ebb and flow; racers which get an early lead stand a good chance of falling behind later in the race. On the final lap racers accelerate towards their sprinting value. This system added new potential for the racers to make “mistakes”. For example, if a racer is not initially boxed in but then suddenly is they may not have enough time to slow down and will crash into the racer in front of him. I did not consider these features undesirable, since in track cycling (a sport in which racers have no breaks) these sorts of scenarios actually occur. The final task was to add a human racer into the pack. The player is not ‘on rails’ in the same way the AIs are. I devised a script that checks with the game manager frequently and approximates the lane and node the racer would be at if they were on rails. The result is a system in which the AI rarely cuts into the player and is capable of drafting off of him. Occasionally the AI will invade the player’s space slightly due to the overlap in time between the various script’s cycles (occasionally a script will not approximate the player’s location soon enough for the racer to react to being blocked). I consider this a fine side effect of my programming, and it is one I could easily tighten up by speeding up the rate of processing. But bike racing is a messy sport and racers make mistakes, so I left it as it currently is.