/// <summary> /// This algorithm does a precise smooth of the path, making it as good as it can get, /// but using CPU more intesively /// </summary> /// <param name="entity">The entity that´s going to move through the path</param> /// <param name="path">The path the algorithm is going to try to smooth</param> /// <remarks> /// The check done for the edge information can fail sometimes, it depends on the map type. /// In complex maps a more carefully check should be done to see if the entity can reach the next edge /// end-point without changing its movement behavior (traversing the same terrain type) /// </remarks> public static void PathSmoothPrecise(MovingEntity entity, List <NavigationEdge> path) { int i, j; i = 0; //This method does the smoothing check between all pairs of nodes trying to see if edges can be removed from the path while (i < path.Count) { j = i + 1; while (j < path.Count) { if (entity.CanMoveBetween(path[i].Start, path[j].End) && path[i].Information == path[j].Information) { path[i].End = path[j].End; path.RemoveRange(i, j - i); i = j; i--; } else { j++; } } i++; } }
/// <summary> /// This method requests a time-sliced search to a position /// </summary> /// <param name="position">The destination of the search</param> /// <returns> /// True if the search can take place (even if later it fails). False if it can´t take place: the start or end positions are /// unreachable for the owner entity (they are out of the geometry or another kind of problem) /// </returns> /// <remarks>A* is used by default as search algorithm</remarks> public bool RequestPathToPosition(Vector3 position) { int closestNodeToEntity, closestNodeToDestination; PathManager <T> .Instance.Unregister(this); destination = position; //If the entity can reach the destination directly, there´s no need to request a search if (owner.CanMoveBetween(owner.Position, destination) == true) { MessageManagerRouter.Instance.SendMessage(0, owner.ID, 0, MessageType.PathReady, null); return(true); } //Get the closest node to the entity closestNodeToEntity = ClosestNodeToPosition(owner.Position); if (closestNodeToEntity == NoNodeFound) { return(false); } //Get the cloest node to the destination closestNodeToDestination = ClosestNodeToPosition(destination); if (closestNodeToDestination == NoNodeFound) { return(false); } //Initialize the search search.Initialize(closestNodeToEntity, closestNodeToDestination); //Register the search in the PathManager PathManager <T> .Instance.Register(this); return(true); }
/// <summary> /// This algorithm does a quick smooth of the path, enough to make it much more better looking /// and without using too much CPU /// </summary> /// <param name="entity">The entity that´s going to move through the path</param> /// <param name="path">The path the algorithm is going to try to smooth</param> /// <remarks> /// The check done for the edge information can fail sometimes, it depends on the map type. /// In complex maps a more carefully check should be done to see if the entity can reach the next edge /// end-point without changing its movement behavior (traversing the same terrain type) /// </remarks> public static void PathSmoothQuick(MovingEntity entity, List <NavigationEdge> path) { int i, j; i = 0; j = 1; //Move through all the edges of the path testing if the entity can move through 2 non-consecutive points //and the edge information is the same in the edges to smooth while (j < path.Count) { if (entity.CanMoveBetween(path[i].Start, path[j].End) && path[i].Information == path[j].Information) { path[i].End = path[j].End; path.RemoveAt(j); } else { i = j; j++; } } }