private void InitializeUnseenList(List <PathfindPriorityQueueItem> unseen, PathfindNode origin, PathfindNode dest, PriorityQueue <PathfindPriorityQueueItem> priority) { foreach (PathfindNode node in graph) { PathfindPriorityQueueItem item = new PathfindPriorityQueueItem(); item.node = node; item.prev = null; float dist = Vector2.Distance(node.transform.position, dest.transform.position); item.distanceToDest = dist; item.pathDistanceFromOrigin = 99999999; // basically infinity if (node == origin) { item.pathDistanceFromOrigin = 0; priority.Enqueue(item); } unseen.Add(item); } }
private void OnTriggerEnter2D(Collider2D collision) { PathfindNode node = collision.GetComponent <PathfindNode>(); if (node != null) { PathInfo path = rigidbody.velocity.x > 0 ? node.PosInfo : node.NegInfo; if (path == null) { return; } if (path.YForce != 0) { rigidbody.AddForce(new Vector2(0, path.YForce)); } if (path.XSpeed != 0) { xSpeed = path.XSpeed; } } }
// Returns a list of tiles that form the shortest path between start and dest public static List<Location> FindPath(Location start, Location dest, IGameState state, List<Location> avoid, LayeredInfluenceMap heat = null, int maxDepth = int.MaxValue) { if (start.Equals(dest) || !state.GetIsPassable(dest) || avoid.Contains(dest)) return null; HashSet<string> closed = new HashSet<string>(); Dictionary<string, PathfindNode> locToNode = new Dictionary<string, PathfindNode>(); List<PathfindNode> open = new List<PathfindNode>(); List<Location> reachable; PathfindNode first = new PathfindNode(start, null, dest, state, heat[start]); open.Add(first); locToNode.Add(MyBot.LocationToKey(first.Position), first); // Repeat until the destination node is reached PathfindNode last = null; while (open.Count > 0) { if (state.TimeRemaining < 10) { MyBot.LogShit("timeout.txt", "stop B - " + state.TimeRemaining); return null; } // Search the best available tile (lowest cost to reach from start, closest to dest) PathfindNode best = null; foreach (PathfindNode next in open) { if (best == null) best = next; if (next.F < best.F) best = next; } if (best.G > maxDepth) return null; //PathfindNode best = open.Min; // Move to closed list open.Remove(best); locToNode.Remove(MyBot.LocationToKey(best.Position)); closed.Add(MyBot.LocationToKey(best.Position)); if (best.Position.Equals(dest)) // Destination added to closed list - almost done! { last = best; break; } // Find tiles adjacent to this tile reachable = GetNeighbours(best.Position, state); string lid; PathfindNode pfn; foreach (Location next in reachable) { if (!state.GetIsPassable(next) || avoid.Contains(next)) // Check if tile is blocked continue; lid = MyBot.LocationToKey(next); if (closed.Contains(lid)) continue; if(locToNode.ContainsKey(lid)) { pfn = locToNode[lid]; if (best.G + 1 < pfn.G) pfn.Parent = best; } else{ pfn = new PathfindNode(next, best, dest, state, heat[next]); open.Add(pfn); locToNode.Add(lid, pfn); } } } if (last == null) return null; // Trace the route from destination to start (using each node's parent property) List<PathfindNode> route = new List<PathfindNode>(); while (last != first && last != null) { route.Add(last); last = last.Parent; } // Reverse route and convert to Points List<Location> path = new List<Location>(); for (int i = route.Count - 1; i >= 0; i--) { path.Add(route[i].Position); } // Return the list of Points return path; }
public PathfindNode(Location position, PathfindNode parent, Location destination, IGameState state, float heat) { this.Position = position; this.Parent = parent; this.E = heat; this.H = state.GetDistance(position, destination); }
// Here we calculate the distance between the current node and the target node private static void CalculateManhattanDistance(PathfindNode currentNode, PathfindNode targetNode) { currentNode.H = ((Mathf.Abs(currentNode.positionEyes.x - targetNode.positionEyes.x) + Mathf.Abs(currentNode.positionEyes.z - targetNode.positionEyes.z) + Mathf.Abs(currentNode.positionEyes.y - targetNode.positionEyes.y)) * 10); }
// Here we calculate the movement cost between 2 points. private static void CalculateMovementCost(PathfindNode currentNode, bool diagonal) { currentNode.G = currentNode.parentNode.G + (diagonal ? 14f : 10f); }
// METHODS // DetectAdjacentNodes() // This automatically creates the surrounding pathnodes public void DetectAdjacentNodes() { if (!pathfinder.ClosedList[this.positionEyes + VectorForward]) { if (!Physics.Linecast(this.positionEyes, this.positionEyes + VectorForward, blockLayer)) { north = FindPathNodeOrCreate(this.pathfinder, this, this.positionEyes + VectorForward, false); } else { if (this.pathfinder.player != null) { this.pathfinder.player.SendConsoleCommand("ddraw.box", 5f, UnityEngine.Color.red, this.positionEyes + VectorForward, 0.5f); } } } if (!pathfinder.ClosedList[this.positionEyes + VectorRight]) { if (!Physics.Linecast(this.positionEyes, this.positionEyes + VectorRight, blockLayer)) { east = FindPathNodeOrCreate(this.pathfinder, this, this.positionEyes + VectorRight, false); } else { if (this.pathfinder.player != null) { this.pathfinder.player.SendConsoleCommand("ddraw.box", 5f, UnityEngine.Color.red, this.positionEyes + VectorRight, 0.5f); } } } if (!pathfinder.ClosedList[this.positionEyes + VectorBack]) { if (!Physics.Linecast(this.positionEyes, this.positionEyes + VectorBack, blockLayer)) { south = FindPathNodeOrCreate(this.pathfinder, this, this.positionEyes + VectorBack, false); } else { if (this.pathfinder.player != null) { this.pathfinder.player.SendConsoleCommand("ddraw.box", 5f, UnityEngine.Color.red, this.positionEyes + VectorBack, 0.5f); } } } if (!pathfinder.ClosedList[this.positionEyes + VectorLeft]) { if (!Physics.Linecast(this.positionEyes, this.positionEyes + VectorLeft, blockLayer)) { west = FindPathNodeOrCreate(this.pathfinder, this, this.positionEyes + VectorLeft, false); } else { if (this.pathfinder.player != null) { this.pathfinder.player.SendConsoleCommand("ddraw.box", 5f, UnityEngine.Color.red, this.positionEyes + VectorLeft, 0.5f); } } } if (!pathfinder.ClosedList[this.positionEyes + VectorForwardRight]) { if (!Physics.Linecast(this.positionEyes, this.positionEyes + VectorForwardRight, blockLayer)) { northeast = FindPathNodeOrCreate(this.pathfinder, this, this.positionEyes + VectorForwardRight, true); } else { if (this.pathfinder.player != null) { this.pathfinder.player.SendConsoleCommand("ddraw.box", 5f, UnityEngine.Color.red, this.positionEyes + VectorForwardRight, 0.5f); } } } if (!pathfinder.ClosedList[this.positionEyes + VectorForwardLeft]) { if (!Physics.Linecast(this.positionEyes, this.positionEyes + VectorForwardLeft, blockLayer)) { northwest = FindPathNodeOrCreate(this.pathfinder, this, this.positionEyes + VectorForwardLeft, true); } else { if (this.pathfinder.player != null) { this.pathfinder.player.SendConsoleCommand("ddraw.box", 5f, UnityEngine.Color.red, this.positionEyes + VectorForwardLeft, 0.5f); } } } if (!pathfinder.ClosedList[this.positionEyes + VectorBackLeft]) { if (!Physics.Linecast(this.positionEyes, this.positionEyes + VectorBackLeft, blockLayer)) { southeast = FindPathNodeOrCreate(this.pathfinder, this, this.positionEyes + VectorBackLeft, true); } else { if (this.pathfinder.player != null) { this.pathfinder.player.SendConsoleCommand("ddraw.box", 5f, UnityEngine.Color.red, this.positionEyes + VectorBackLeft, 0.5f); } } } if (!pathfinder.ClosedList[this.positionEyes + VectorBackRight]) { if (!Physics.Linecast(this.positionEyes, this.positionEyes + VectorBackRight, blockLayer)) { southwest = FindPathNodeOrCreate(this.pathfinder, this, this.positionEyes + VectorBackRight, true); } else { if (this.pathfinder.player != null) { this.pathfinder.player.SendConsoleCommand("ddraw.box", 5f, UnityEngine.Color.red, this.positionEyes + VectorBackRight, 0.5f); } } } }
public List <Vector2> pathFindTo(Vector2 origin, Vector2 dest, TileMap map) { tileMap = map; open.clear(); closed.clear(); float d1Cost = map.getTileSize(); float d2Cost = Mathf.Sqrt(d1Cost * d1Cost * 2); Vector2Int start = map.getTileCoords(origin); end = map.getTileCoords(dest); open.insertNode(new PathfindNode(start)); while (open.size() > 0) { PathfindNode currNode = open.pop(); closed.insertNode(currNode); if (currNode.index == end) { break; } for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { if (x == 0 && y == 0) { continue; } Vector2Int neighbor = currNode.index + new Vector2Int(x, y); GameObject g = map.getTile(neighbor); if (g == null || g.tag == "Wall") { continue; } bool flag = false; for (int i = 0; i < g.transform.childCount; i++) { if (g.transform.GetChild(i).tag == "Wall") { flag = true; break; } } if (flag) { continue; } float cost = (x == 0 || y == 0) ? d1Cost : d2Cost; float currCost = currNode.cachedCost + cost; PathfindNode n = open.findNode(neighbor); if (n != null && (currCost < n.cachedCost)) { open.removeNode(n); } n = closed.findNode(neighbor); if (n != null && (currCost < n.cachedCost)) { closed.removeNode(n); } if (open.findNode(neighbor) == null && closed.findNode(neighbor) == null) { n = new PathfindNode(neighbor); n.parent = currNode; n.weight = calculateWeight(neighbor); n.cachedCost = currCost; open.insertNode(n); } } } } if (closed.size() > 0) { List <Vector2> list = new List <Vector2>(); PathfindNode n = closed.pop(); while (n != null) { list.Insert(0, tileMap.getTile(n.index).transform.position); n = n.parent; } return(list); } return(null); }
private void handleMouseEvent(SceneView sceneView) { if (Editable == false) { return; } if (pathfindManager == null) { DisableEditor(); return; } //ComputeSelectSquare(sceneView); bool validEvent = (Event.current.type == EventType.MouseDown) && Event.current.button == 0; if (validEvent == false) { return; } m_moussePressed = true; m_squareFirstPoint = Event.current.mousePosition; NawakTools.s_tileSize = (int)pathfindManager.tileSize; Vector3 mouseposition = Event.current.mousePosition; var plane = new Plane(new Vector3(0, 0, 1), Vector3.zero); Ray ray = sceneView.camera.ScreenPointToRay(mouseposition); ray = HandleUtility.GUIPointToWorldRay(mouseposition); Vector3 worldPosition = Vector3.zero; float enterPoint = 0; if (plane.Raycast(ray, out enterPoint)) { bool onAdding = false; worldPosition = ray.origin + ray.direction * enterPoint; if (Event.current.type == EventType.MouseMove && Event.current.modifiers == EventModifiers.Shift) { } if (Event.current.type == EventType.MouseDown && Event.current.button == 0) { Point selectedTile = null; PathfindNode selectedNode = null; if (Event.current.modifiers == EventModifiers.Alt) { } if (onAdding) { } else { //selectedTile = NawakTools.worldPositionToCellCenter(worldPosition); selectedTile = new Point(new Vector2((int)((-pathfindManager.transform.position.x + worldPosition.x + 1.25f / 2) / (1.25f)) , (int)((-pathfindManager.transform.position.y + worldPosition.y + 1.25f / 2) / (1.25f)))); selectedNode = pathfindManager.GetNodeAt(selectedTile); } if (Event.current.modifiers != EventModifiers.Control && onAdding == false) { OnUnselect(); m_selectecPoints.Clear(); } if (selectedNode != null) { if (m_selectecPoints.Contains(selectedNode)) { OnUnselect(); m_selectecPoints.Remove(selectedNode); } else { m_selectecPoints.Add(selectedNode); } } OnSelect(); Repaint(); } EditorUtility.SetDirty(pathfindManager); } }
// Returns a list of tiles that form the shortest path between start and dest public static List<Location> FindPath(Location start, Location dest, IGameState state) { if (start.Equals(dest) || !state.GetIsPassable(dest)) return null; HashSet<Location> closed = new HashSet<Location>(); Dictionary<Location, PathfindNode> locToNode = new Dictionary<Location, PathfindNode>(); List<PathfindNode> open = new List<PathfindNode>(); List<Location> reachable; PathfindNode first = new PathfindNode(start, null, dest, state); open.Add(first); locToNode.Add(first.Position, first); // Repeat until the destination node is reached PathfindNode last = null; while (open.Count > 0) { // Search the best available tile (lowest cost to reach from start, closest to dest) PathfindNode best = null; foreach (PathfindNode next in open) { if (best == null) best = next; if (next.F < best.F) best = next; } //PathfindNode best = open.Min; // Move to closed list open.Remove(best); locToNode.Remove(best.Position); closed.Add(best.Position); if (best.Position.Equals(dest)) // Destination added to closed list - almost done! { last = best; break; } // Find tiles adjacent to this tile reachable = GetNeighbours(best.Position, state); PathfindNode pfn; foreach (Location next in reachable) { if (!state.GetIsPassable(next)) // Check if tile is blocked continue; if (closed.Contains(next)) continue; if(locToNode.ContainsKey(next)) { pfn = locToNode[next]; if (best.G + 1 < pfn.G) pfn.Parent = best; } else{ pfn = new PathfindNode(next, best, dest, state); open.Add(pfn); locToNode.Add(next, pfn); } } } if (last == null) return null; // Trace the route from destination to start (using each node's parent property) List<PathfindNode> route = new List<PathfindNode>(); while (last != first && last != null) { route.Add(last); last = last.Parent; } // Reverse route and convert to Points List<Location> path = new List<Location>(); for (int i = route.Count - 1; i >= 0; i--) { path.Add(route[i].Position); } // Return the list of Points return path; }
public void ChaseState() { if (Vector2.Distance(transform.position, PlayerTransform.transform.position) > maxDistance) { anim.SetBool("Chase", false); } PathfindNode dest = FindNearestGraphNode(PlayerTransform); PathfindNode origin = FindNearestGraphNode(this.transform); if (dest != null && origin != null && dest != oldDestination) { // Run A star algorithm and skip any unessary path nodes path = pathfinder.FindPath(origin, dest); // Skip the first one if unnecessary if (path.Count > 1) { int horizontalDirection = 0; if (path[1].transform.position.x - path[0].transform.position.x > nodeRadiusThreshold) { horizontalDirection = 1; } else if (path[1].transform.position.x - path[0].transform.position.x < -nodeRadiusThreshold) { horizontalDirection = -1; } int verticalDirection = 0; if (path[1].transform.position.y - path[0].transform.position.y > nodeRadiusThreshold) { verticalDirection = 1; } else if (path[1].transform.position.y - path[0].transform.position.y < -nodeRadiusThreshold) { verticalDirection = -1; } int enemyToRight = 0; if (transform.position.x - path[0].transform.position.x > nodeRadiusThreshold) { enemyToRight = 1; } else if (transform.position.x - path[0].transform.position.x < -nodeRadiusThreshold) { enemyToRight = -1; } int enemyAbove = 0; if (transform.position.y - path[0].transform.position.y > nodeRadiusThreshold) { enemyAbove = 1; } else if (transform.position.y - path[0].transform.position.y < -nodeRadiusThreshold) { enemyAbove = -1; } if ((horizontalDirection == enemyToRight || horizontalDirection == 0) && (verticalDirection == enemyAbove || verticalDirection == 0)) { indexInPath++; } } if (indexInPath < path.Count) { nextWayPoint = path[indexInPath].transform; } indexInPath = 0; oldDestination = dest; } // Determine what point the player is trying to get to if (indexInPath >= path.Count) { // Chase Player nextWayPoint = PlayerTransform; } else { nextWayPoint = path[indexInPath].transform; // If you get to the next waypoint and pass it, increment index if (Vector2.Distance(transform.position, nextWayPoint.position) < nodeRadiusThreshold) { indexInPath++; if (indexInPath < path.Count) { nextWayPoint = path[indexInPath].transform; } } } if (nextWayPoint != null) { if (Vector2.Distance(transform.position, PlayerTransform.position) < 0.1f * nodeRadiusThreshold) { rb.velocity = new Vector2(0f, 0f); } else { Vector2 dir = nextWayPoint.position - transform.position; dir.Normalize(); rb.velocity = new Vector2(dir.x * chaseSpeed * Time.deltaTime, dir.y * chaseSpeed * Time.deltaTime); if ((nextWayPoint.position.x > transform.position.x && !facingRight) || (nextWayPoint.position.x < transform.position.x && facingRight)) { Flip(); } } } }
// Returns a list of tiles that form the shortest path between start and dest public static List <Location> FindPath(Location start, Location dest, IGameState state, List <Location> avoid, LayeredInfluenceMap heat = null, int maxDepth = int.MaxValue) { if (start.Equals(dest) || !state.GetIsPassable(dest) || avoid.Contains(dest)) { return(null); } HashSet <string> closed = new HashSet <string>(); Dictionary <string, PathfindNode> locToNode = new Dictionary <string, PathfindNode>(); List <PathfindNode> open = new List <PathfindNode>(); List <Location> reachable; PathfindNode first = new PathfindNode(start, null, dest, state, heat[start]); open.Add(first); locToNode.Add(MyBot.LocationToKey(first.Position), first); // Repeat until the destination node is reached PathfindNode last = null; while (open.Count > 0) { if (state.TimeRemaining < 10) { MyBot.LogShit("timeout.txt", "stop B - " + state.TimeRemaining); return(null); } // Search the best available tile (lowest cost to reach from start, closest to dest) PathfindNode best = null; foreach (PathfindNode next in open) { if (best == null) { best = next; } if (next.F < best.F) { best = next; } } if (best.G > maxDepth) { return(null); } //PathfindNode best = open.Min; // Move to closed list open.Remove(best); locToNode.Remove(MyBot.LocationToKey(best.Position)); closed.Add(MyBot.LocationToKey(best.Position)); if (best.Position.Equals(dest)) // Destination added to closed list - almost done! { last = best; break; } // Find tiles adjacent to this tile reachable = GetNeighbours(best.Position, state); string lid; PathfindNode pfn; foreach (Location next in reachable) { if (!state.GetIsPassable(next) || avoid.Contains(next)) // Check if tile is blocked { continue; } lid = MyBot.LocationToKey(next); if (closed.Contains(lid)) { continue; } if (locToNode.ContainsKey(lid)) { pfn = locToNode[lid]; if (best.G + 1 < pfn.G) { pfn.Parent = best; } } else { pfn = new PathfindNode(next, best, dest, state, heat[next]); open.Add(pfn); locToNode.Add(lid, pfn); } } } if (last == null) { return(null); } // Trace the route from destination to start (using each node's parent property) List <PathfindNode> route = new List <PathfindNode>(); while (last != first && last != null) { route.Add(last); last = last.Parent; } // Reverse route and convert to Points List <Location> path = new List <Location>(); for (int i = route.Count - 1; i >= 0; i--) { path.Add(route[i].Position); } // Return the list of Points return(path); }
public void AddNode(Point p, PathfindNode newNode) { AllNodes.Add(newNode); ArrayArea[p.X, p.Y] = newNode; DicoArea.Add(p, newNode); }
public void AddNode(Point p) { PathfindNode newNode = new PathfindNode(p); AddNode(p, newNode); }
public bool Contains(PathfindNode curentPoint) { return(GetNodeAt(curentPoint.Point) != null); return(AllNodes.Contains(curentPoint)); }