Commit 4353c969 authored by ffperes's avatar ffperes

Lab 03 - taks 4 and 5

Instructions to use -
Run the scene 3, click anywhere in the plane ground and the agent will
go towards to the nearest node of the mouse clink position
parent 863c81b6
......@@ -6,7 +6,7 @@
<ProductVersion>10.0.20506</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<RootNamespace></RootNamespace>
<ProjectGuid>{5852E455-B90A-DA33-FB45-BE959AFEB886}</ProjectGuid>
<ProjectGuid>{4F260D9A-13DC-3512-D9AC-A60A53AB9973}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<AssemblyName>Assembly-CSharp</AssemblyName>
......@@ -46,6 +46,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Assets\Navigation\Scripts\Agent.cs" />
<Compile Include="Assets\Navigation\Scripts\AgentController.cs" />
<Compile Include="Assets\Navigation\Scripts\Node.cs" />
<Reference Include="UnityEngine.Advertisements">
<HintPath>C:/Program Files/Unity/Editor/Data/UnityExtensions/Unity/Advertisements/UnityEngine.Advertisements.dll</HintPath>
......
This diff is collapsed.
fileFormatVersion: 2
guid: a35ee492e2aa8bd4d8b8adf502ee633d
timeCreated: 1449226988
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
......@@ -40,7 +40,7 @@ MeshRenderer:
m_CastShadows: 1
m_ReceiveShadows: 1
m_Materials:
- {fileID: 0}
- {fileID: 2100000, guid: 7d3474274044ba14d815ba577da7c399, type: 2}
m_SubsetIndices:
m_StaticBatchRoot: {fileID: 0}
m_UseLightProbes: 1
......
......@@ -27,7 +27,9 @@ public class Agent : MonoBehaviour {
// path will store all nodes selected by the algorithm to be part
// of the path
private List<Node> path = new List<Node>();
public List<Node> path = new List<Node>();
public List<Node> myGraph = new List<Node> ();
private int key = 0;
......@@ -42,76 +44,38 @@ public class Agent : MonoBehaviour {
// It will also check for the space bar input and give
// feedback at the console for each start, target node was selected and
// the route with the shortest path from the beginning to target
void Update () {
if (Input.GetMouseButtonDown(0))
{
start = getClosestToClick();
Debug.Log("Start set to " + start.name);
}
if (Input.GetMouseButtonDown(1))
{
target = getClosestToClick();
Debug.Log("Target set to " + target.name);
}
if (Input.GetKeyDown(KeyCode.Space))
{
foreach (Node n in Node.nodes)
{
if(n != null){
n.GetComponent<MeshRenderer>().material = nodeMaterialAtStart;
}
}
Debug.Log("The shortest path found is from Route found via following nodes in order...");
foreach (Node n in path = Astar())
{
n.GetComponent<MeshRenderer>().material = nodePathMaterial;
Debug.Log(n.name);
}
}
}
// This function will track the mouse clicks to then check each node
// is the closest node from the click position by using raycast
// and then returning that node
private Node getClosestToClick()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity))
{
Node closest = null;
double closestDist = Mathf.Infinity;
double tmpDist;
foreach (Node n in Node.nodes)
{
if(n != null){
if ((tmpDist = Vector3.Distance(n.transform.position, hit.point)) < closestDist)
{
closest = n;
closestDist = tmpDist;
}
protected Node getClosestNode(Vector3 searchPos) //returns closest node in the graph to a specified point, returns null if no node can be found
{
Node closest = null;
double cdist = Mathf.Infinity;
double tmpDist;
if (myGraph.Count > 0) {
foreach (Node n in myGraph)
{
if ((tmpDist = Vector3.Distance(n.transform.position, searchPos)) < cdist)
{
closest = n;
cdist = tmpDist;
}
}
return closest;
}
else
{
return null;
}
}
}
}
return closest;
}
// My path finding algorithm
// https://en.wikipedia.org/wiki/A*_search_algorithm
// It contains a list with the shortest pah
// an open and closed list, to manipulate the nodes be visited and already visited
// and two booleans, one to keeping search till the current node is the target node
// and a second to decide when to reverse the path to reconstruct it
private List<Node> Astar()
public List<Node> Astar(Node startPosition, Node targetPosition)
{
List<Node> shortestPath = new List<Node>();
List<Node> open = new List<Node>();
List<Node> closed = new List<Node>();
open.Add(start);
start.addCost(key, 0);
open.Add(startPosition);
startPosition.addCost(key, 0);
bool searching = true;
bool backtracing = false;
......@@ -122,13 +86,13 @@ public class Agent : MonoBehaviour {
int best = 0; //finds the heuristically quickest node to navigate next
for (int i = 0; i < open.Count; i++)
{
if (open[i].heuristic(target) + open[i].getCost(key) < open[best].heuristic(target) + open[best].getCost(key))
if (open[i].heuristic(targetPosition) + open[i].getCost(key) < open[best].heuristic(targetPosition) + open[best].getCost(key))
{
best = i;
}
}
if (open[best] == target) // if the current node is the target, will exit the loop because of the boolean
if (open[best] == targetPosition) // if the current node is the target, will exit the loop because of the boolean
{
shortestPath.Add(open[best]);
backtracing = true;
......
/* INSTRUCTIONS HOW TO USE
*
* Run the engine.
* Click with left mouse button near a node
* And see the sphere to calculate the shortest path and reach that node
*
*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class AgentController : Agent {
Rigidbody rb;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update () {
if (myGraph.Count > 0) {
// It will calculate by using the mouse left click, the nearest node from that position
if (Input.GetMouseButtonDown (0)) {
path = Astar (getClosestNode (transform.position), getClosestToClick ());
}
if (path.Count > 0) { //iif the number of paths, or nodes to reach the goal is bigger then zero
//Will add a force to its speed, changing the position
rb.AddForce (path [0].transform.position - transform.position);
// Uses magnitude to turn the agent at the same time that it imprimes the speed to 3
rb.velocity = Vector3.ClampMagnitude (rb.velocity, 3);
// Check the distance between the agent and the current node being seek
if (Vector3.Distance (transform.position, path [0].transform.position) < 1) {
// reduces the speed to 2 when the agent aprroach the node being seek
rb.velocity = Vector3.ClampMagnitude (rb.velocity, 2);
if (Vector3.Distance (transform.position, path [0].transform.position) < .5){
// set the speed to zero when reaches the goal
rb.velocity = Vector3.ClampMagnitude (rb.velocity, 0);
}
if (path.Count > 1) {
path.Remove (path [0]); // remove path if there is no more nodes to search
}
}
}
}
}
// uses raycast to calculate the mouse position at the oment of the click
// and compares whth the graph, then will return the node that is closer
// to the point clicked by the mouse
private Node getClosestToClick()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity))
{
return getClosestNode(hit.point);
}
else
{
return null;
}
}
}
fileFormatVersion: 2
guid: ed249c384c4f48c42ad0b74a7d2787fc
timeCreated: 1449227131
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2008
Project("{25CFA95E-C11C-224C-FF1D-709BA4F43053}") = "Lab_02", "Assembly-CSharp.csproj", "{4F260D9A-13DC-3512-D9AC-A60A53AB9973}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4F260D9A-13DC-3512-D9AC-A60A53AB9973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4F260D9A-13DC-3512-D9AC-A60A53AB9973}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F260D9A-13DC-3512-D9AC-A60A53AB9973}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F260D9A-13DC-3512-D9AC-A60A53AB9973}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Assembly-CSharp.csproj
Policies = $0
$0.TextStylePolicy = $1
$1.inheritsSet = null
$1.scope = text/x-csharp
$0.CSharpFormattingPolicy = $2
$2.inheritsSet = Mono
$2.inheritsScope = text/x-csharp
$2.scope = text/x-csharp
$0.TextStylePolicy = $3
$3.FileWidth = 120
$3.TabWidth = 4
$3.IndentWidth = 4
$3.EolMarker = Unix
$3.inheritsSet = Mono
$3.inheritsScope = text/plain
$3.scope = text/plain
EndGlobalSection
EndGlobal
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment