using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Node {
public int GridX, GridY, MoveCost, ManhattanCost;
public bool isWall;
public Vector3 Position;
public Node Parent;
public int FCost
{
get
{
return MoveCost + ManhattanCost;
}
}
public Node(bool p_isAWall, Vector3 p_position, int p_gridX, int p_gridY)
{
isWall = p_isAWall;
Position = p_position;
GridX = p_gridX;
GridY = p_gridY;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Pathfinding : MonoBehaviour
{
ToGoScript Grid;
private Node StartNode;
private Node EndNode;
private int MoveCost;
private List<Node> OpenList = new List<Node>();
List<Node> Finalpath = new List<Node>();
Node CurrentNode;
private HashSet<Node> ClosedList = new HashSet<Node>();
private void Awake()
{
Grid = GetComponent<ToGoScript>();
}
private void Update()
{
OpenList = new List<Node>();
ClosedList = new HashSet<Node>();
AStarPath(Grid.StartObject.transform.position, Grid.EndObject.transform.position);
}
void AStarPath(Vector3 StartPos, Vector3 EndPos)
{
StartNode = Grid.NodeFromWorldPosition(StartPos);
OpenList.Add(StartNode);
EndNode = Grid.NodeFromWorldPosition(EndPos);
while (OpenList.Count > 0)
{
CurrentNode = OpenList[0];
for (int i = 1; i < OpenList.Count; i++)
{
if (OpenList[i].FCost < CurrentNode.FCost || OpenList[i].FCost == CurrentNode.FCost && OpenList[i].ManhattanCost < CurrentNode.ManhattanCost)
{
CurrentNode = OpenList[i];
}
}
OpenList.Remove(CurrentNode);
ClosedList.Add(CurrentNode);
if (CurrentNode == EndNode)
{
GetFinalPath(StartNode, EndNode);
break;
}
foreach (Node NeighbourNodes in Grid.GetNodes(CurrentNode))
{
if (NeighbourNodes.isWall || ClosedList.Contains(NeighbourNodes))
{
continue;
}
MoveCost = CurrentNode.MoveCost + ManhattanDistance(CurrentNode, NeighbourNodes);
if (MoveCost < NeighbourNodes.MoveCost || !OpenList.Contains(NeighbourNodes))
{
NeighbourNodes.MoveCost = MoveCost;
NeighbourNodes.ManhattanCost = ManhattanDistance(NeighbourNodes, EndNode);
NeighbourNodes.Parent = CurrentNode;
if (!OpenList.Contains(NeighbourNodes))
{
OpenList.Add(NeighbourNodes);
}
}
}
}
}
void GetFinalPath(Node StartNode, Node EndNode)
{
Finalpath.Clear();
CurrentNode = EndNode;
while (CurrentNode != StartNode)
{
Finalpath.Add(CurrentNode);
CurrentNode = CurrentNode.Parent;
}
Finalpath.Reverse();
Grid.FinalPath = Finalpath;
}
int ManhattanDistance(Node p_NodeA, Node p_NodeB)
{
return Mathf.Abs(p_NodeA.GridX - p_NodeB.GridX) + Mathf.Abs(p_NodeA.GridY - p_NodeB.GridY);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ToGoScript : MonoBehaviour
{
public LayerMask WallMask;
private Vector2 gridWorldSize = new Vector2(30, 30);
private float nodeRaidus = 0.5f;
private float Distance = 0.0f;
Node[,] grid;
[HideInInspector]
public List<Node> FinalPath = new List<Node>();
private List<Vector3> nodePosition = new List<Vector3>();
List<Node> NeighbouringNodes = new List<Node>();
[HideInInspector]
public GameObject StartObject;
[HideInInspector]
public GameObject EndObject;
public float UpdatePosition = 50f;
float nodeDiameter;
int GridSizeX, GridSizeY;
int xCheck, yCheck;
int randPos = 0;
private void Start()
{
StartObject = Resources.Load("StartPos") as GameObject ;
EndObject = Resources.Load("EndPos") as GameObject;
StartObject = Instantiate<GameObject>(StartObject, Vector3.zero, transform.rotation);
EndObject = Instantiate<GameObject>(EndObject, Vector3.zero, transform.rotation);
nodeDiameter = nodeRaidus + nodeRaidus;
GridSizeY = Mathf.RoundToInt(gridWorldSize.y / nodeDiameter);
GridSizeX = Mathf.RoundToInt(gridWorldSize.x / nodeDiameter);
InvokeRepeating("UpdateLocation", UpdatePosition, UpdatePosition);
CreateGrid();
StartObject.transform.position = RandomPosition();
EndObject.transform.position = RandomPosition();
}
void UpdateLocation()
{
StartObject.transform.position = RandomPosition();
EndObject.transform.position = RandomPosition();
}
Vector3 RandomPosition()
{
if (nodePosition.Count < 1)
{
foreach (Node node in grid)
{
if (!node.isWall)
nodePosition.Add(node.Position);
}
}
randPos = Random.Range(0, nodePosition.Count);
return nodePosition[randPos];
}
void CreateGrid()
{
grid = new Node[Mathf.RoundToInt(GridSizeX), Mathf.RoundToInt(GridSizeY)];
Vector3 bottomLeft = transform.position - Vector3.right * gridWorldSize.x / 2 - Vector3.forward * gridWorldSize.y / 2;
for (int x = 0; x < GridSizeX; x++)
{
for (int y = 0; y < GridSizeY; y++)
{
Vector3 worldPoint = bottomLeft + Vector3.right * (x * nodeDiameter + nodeRaidus) + Vector3.forward * (y * nodeDiameter + nodeRaidus);
bool Wall = false;
if (Physics.CheckSphere(worldPoint, nodeRaidus, WallMask))
{
Wall = true;
}
grid[x, y] = new Node(Wall, worldPoint, x, y);
}
}
}
bool CheckNextNode(int gridX, int gridY)
{
if (gridX >= 0 && gridX < GridSizeX)
{
if (gridY >= 0 && gridY < GridSizeY)
{
return true;
}
}
return false;
}
public List<Node> GetNodes(Node p_Node)
{
NeighbouringNodes.Clear();
xCheck = p_Node.GridX + 1;
yCheck = p_Node.GridY;
if(CheckNextNode(xCheck, yCheck))
{
NeighbouringNodes.Add(grid[xCheck, yCheck]);
}
xCheck = p_Node.GridX - 1;
yCheck = p_Node.GridY;
if (CheckNextNode(xCheck, yCheck))
{
NeighbouringNodes.Add(grid[xCheck, yCheck]);
}
xCheck = p_Node.GridX + 1;
yCheck = p_Node.GridY + 1;
if (CheckNextNode(xCheck, yCheck))
{
NeighbouringNodes.Add(grid[xCheck, yCheck]);
}
xCheck = p_Node.GridX + 1;
yCheck = p_Node.GridY - 1;
if (CheckNextNode(xCheck, yCheck))
{
NeighbouringNodes.Add(grid[xCheck, yCheck]);
}
xCheck = p_Node.GridX - 1;
yCheck = p_Node.GridY + 1;
if (CheckNextNode(xCheck, yCheck))
{
NeighbouringNodes.Add(grid[xCheck, yCheck]);
}
xCheck = p_Node.GridX - 1;
yCheck = p_Node.GridY - 1;
if (CheckNextNode(xCheck, yCheck))
{
NeighbouringNodes.Add(grid[xCheck, yCheck]);
}
xCheck = p_Node.GridX;
yCheck = p_Node.GridY + 1;
if (CheckNextNode(xCheck, yCheck))
{
NeighbouringNodes.Add(grid[xCheck, yCheck]);
}
xCheck = p_Node.GridX;
yCheck = p_Node.GridY - 1;
if (CheckNextNode(xCheck, yCheck))
{
NeighbouringNodes.Add(grid[xCheck, yCheck]);
}
return NeighbouringNodes;
}
public Node NodeFromWorldPosition(Vector3 p_worldPos)
{
return grid[Mathf.RoundToInt((GridSizeX - 1) * ((p_worldPos.x + gridWorldSize.x / 2) / gridWorldSize.x)),
Mathf.RoundToInt((GridSizeY - 1) * ((p_worldPos.z + gridWorldSize.y / 2) / gridWorldSize.y))];
}
private void OnDrawGizmos()
{
Gizmos.DrawWireCube(transform.position, new Vector3(gridWorldSize.x, 1, gridWorldSize.y));
if (grid != null)
{
foreach (Node node in grid)
{
if (node.isWall)
{
Gizmos.color = Color.blue;
}
else
{
Gizmos.color = Color.yellow;
}
if (FinalPath != null)
{
if (FinalPath.Contains(node))
{
Gizmos.color = Color.red;
}
}
Gizmos.DrawCube(node.Position, Vector3.one * (nodeDiameter - Distance));
}
}
}
}