// This takes your current path, if you have one, and extends it one stage towards a destination. // NEEDS WORK !!! private void ExtendCurrentPathTowards(Vector3 destination) { // If you actually HAVE a current path if (currentPath.Count > 1) { // NEEDS CHANGE. This function just walks to player with small chance of error. Not good. // He should actually try to figure out where to go. Node_Wrapper bestExtension = currentPath[currentPath.Count - 1]; foreach (Node_Wrapper node in currentPath[currentPath.Count - 1].neighbours) { if (Vector3.Distance(node.position, destination) < Vector3.Distance(bestExtension.position, destination) && Random.Range(1, 20) < 11 + (2)) // This adds random chance that he'll walk wrong. { bestExtension = node; } } currentPath.Add(bestExtension); } }
private void TeleportToSafety() { if (nodeList.Count < 1) { return; } float RandomFleeDistance = maximumDistanceFromPlayer; Node_Wrapper bestEscapeNode = nodeList[0]; foreach (Node_Wrapper node in nodeList) { if (!IsTransformVisibleFrom(node.position, player)) { if (Mathf.Abs(Vector3.Distance(node.position, player.position) - RandomFleeDistance) < Mathf.Abs(Vector3.Distance(bestEscapeNode.position, player.position) - RandomFleeDistance)) { bestEscapeNode = node; } } } transform.position = bestEscapeNode.position; return; }
private const float MAX_NEIGHBOUR_DISTANCE = 40F; // This is in meters. #endregion Fields #region Constructors public Node_Wrapper(GameObject node) { gameobject = node; thisNode = this; position = node.transform.position; }
private const float MAX_NEIGHBOUR_DISTANCE = 40F; // This is in meters. public Node_Wrapper(GameObject node) { gameobject = node; thisNode = this; position = node.transform.position; }
// Murderer finds the most effective path from himself to the defined object. // The function overwrites murderer's current path with the new one it finds. private void FindPathTo(Transform destination) { if (nodeList.Count < 1) { pathIsImpossible = true; return; } // Find the nodes closest to start and goal Node_Wrapper startNode = null; Node_Wrapper goalNode = null; foreach (Node_Wrapper node in nodeList) { // Set startnode if this node is closer than the closest so far. if (IsTransformVisibleFrom(node.position, transform) || (transform.position - node.position).sqrMagnitude < 0.5F) { if (startNode != null) { if ((transform.position - node.position).sqrMagnitude < (transform.position - startNode.position).sqrMagnitude) { startNode = node; } } else { startNode = node; } } // Set goalnode if this node is closer than the closest so far. if (IsTransformVisibleFrom(node.position, destination, new string[] { "Door" }) || (destination.position - node.position).sqrMagnitude < 0.5F) { if (goalNode != null) { if ((destination.position - node.position).sqrMagnitude < (destination.position - goalNode.position).sqrMagnitude) { goalNode = node; } } else { goalNode = node; } } } if (startNode == null || goalNode == null) { currentPath.Clear(); pathIsImpossible = true; return; } // A* algorithm int failSafe = 0; List <Node_Wrapper> openList = new List <Node_Wrapper>(); List <Node_Wrapper> closedList = new List <Node_Wrapper>(); openList.Add(startNode); while (openList.Count > 0 && failSafe < 1000F) { failSafe++; // This is to find element with lowest score. Node_Wrapper bestNode = null; float bestPathScore = float.MaxValue; foreach (Node_Wrapper node in openList) { float nodeScore = node.distanceTraveled + ((node.position - goalNode.position).sqrMagnitude / 2); if (nodeScore < bestPathScore) { bestNode = node; bestPathScore = nodeScore; } } // Find all neighbours of that node, that haven't been tried out yet. foreach (Node_Wrapper node in bestNode.neighbours) { if (!openList.Contains(node) && !closedList.Contains(node)) { node.parentNode = bestNode; node.distanceTraveled = bestNode.distanceTraveled + (bestNode.position - node.position).sqrMagnitude; openList.Add(node); } else if (node.distanceTraveled > bestNode.distanceTraveled + (bestNode.position - node.position).sqrMagnitude) { node.parentNode = bestNode; node.distanceTraveled = bestNode.distanceTraveled + (bestNode.position - node.position).sqrMagnitude; } } if (bestNode.position != goalNode.position) { closedList.Add(bestNode); openList.Remove(bestNode); } else { currentPath = bestNode.PathHere(); // JIPPI! pathStage = 0; arrivedAtPathEnd = false; pathIsImpossible = false; break; } } // Is the path impossible?? if (openList.Count <= 0 || failSafe >= 1000F) { pathIsImpossible = true; } // Cleans up! foreach (Node_Wrapper node in nodeList) { node.parentNode = null; node.distanceTraveled = 0F; } }