/// <summary> /// Gets the walkable successors of the specified node. /// </summary> /// <param name="current">The current node.</param> /// <param name="successorArray">The array to fill with successors.</param> /// <returns> /// All walkable successors of the node. /// </returns> protected override void GetWalkableSuccessors(IPathNode current, DynamicArray<IPathNode> successorArray) { _neighbours.Clear(); if (current.predecessor == null) { current.GetWalkableNeighbours(_neighbours, _unitProps, _cutCorners, false); } else if (current is IPortalNode) { current.GetWalkableNeighbours(successorArray, _unitProps, _cutCorners, false); return; } else { var dirFromPredecessor = current.predecessor.GetDirectionTo(current); PruneNeighbours(current, dirFromPredecessor); } var neighbourCount = _neighbours.count; for (int i = 0; i < neighbourCount; i++) { var n = _neighbours[i]; if (n == null) { break; } var dirToNeighbour = current.GetDirectionTo(n); var jp = Jump(current, dirToNeighbour); if (jp != null) { successorArray.Add(jp); } } }
private void PruneNeighbours(IPathNode current, VectorXZ direction) { if (direction.x != 0) { if (direction.z != 0) { //Natural neighbours var nTop = current.TryGetWalkableNeighbour(0, direction.z, _unitProps, _neighbours); var nRight = current.TryGetWalkableNeighbour(direction.x, 0, _unitProps, _neighbours); if (_cutCorners) { if (nTop || nRight) { current.TryGetWalkableNeighbour(direction.x, direction.z, _unitProps, _neighbours); } //Forced neighbours? The left/down is as seen from a normal view of the grid, i.e. not seen from the direction of movement (well direction left corner diagonal) var nLeft = current.GetNeighbour(-direction.x, 0); if (nLeft != null && !nLeft.IsWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(-direction.x, direction.z, _unitProps, _neighbours); } var nDown = current.GetNeighbour(0, -direction.z); if (nDown != null && !nDown.IsWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(direction.x, -direction.z, _unitProps, _neighbours); } } else { if (nTop && nRight) { current.TryGetWalkableNeighbour(direction.x, direction.z, _unitProps, _neighbours); } } } else { //Natural neighbour current.TryGetWalkableNeighbour(direction.x, 0, _unitProps, _neighbours); //Forced neighbours? if (_cutCorners) { var nUp = current.GetNeighbour(0, 1); if (nUp != null && !nUp.IsWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(direction.x, 1, _unitProps, _neighbours); } var nDown = current.GetNeighbour(0, -1); if (nDown != null && !nDown.IsWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(direction.x, -1, _unitProps, _neighbours); } } else { var nUpBack = current.GetNeighbour(-direction.x, 1); if (nUpBack != null && !nUpBack.IsWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(0, 1, _unitProps, _neighbours); current.TryGetWalkableNeighbour(direction.x, 1, _unitProps, _neighbours); } var nDownBack = current.GetNeighbour(-direction.x, -1); if (nDownBack != null && !nDownBack.IsWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(0, -1, _unitProps, _neighbours); current.TryGetWalkableNeighbour(direction.x, -1, _unitProps, _neighbours); } } } } else { //Portals return Vector3.zero as the direction, and for those we need to start over on the new grid. if (direction.z == 0) { current.GetWalkableNeighbours(_neighbours, _unitProps, _cutCorners, false); return; } //Natural neighbour current.TryGetWalkableNeighbour(0, direction.z, _unitProps, _neighbours); //Forced neighbours? The left/right is as seen from a normal view of the grid, i.e. not seen from the direction of movement (well direction bottom up) if (_cutCorners) { var nLeft = current.GetNeighbour(-1, 0); if (nLeft != null && !nLeft.IsWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(-1, direction.z, _unitProps, _neighbours); } var nRight = current.GetNeighbour(1, 0); if (nRight != null && !nRight.IsWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(1, direction.z, _unitProps, _neighbours); } } else { var nLeftDown = current.GetNeighbour(-1, -direction.z); if (nLeftDown != null && !nLeftDown.IsWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(-1, 0, _unitProps, _neighbours); current.TryGetWalkableNeighbour(-1, direction.z, _unitProps, _neighbours); } var nRightDown = current.GetNeighbour(1, -direction.z); if (nRightDown != null && !nRightDown.IsWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(1, 0, _unitProps, _neighbours); current.TryGetWalkableNeighbour(1, direction.z, _unitProps, _neighbours); } } } }
private void PruneNeighbours(IPathNode current, VectorXZ direction) { if (direction.x != 0) { if (direction.z != 0) { //Natural neighbours var nTop = current.TryGetWalkableNeighbour(0, direction.z, _unitProps, _neighbours); var nRight = current.TryGetWalkableNeighbour(direction.x, 0, _unitProps, _neighbours); if (_cutCorners) { if (nTop || nRight) { current.TryGetWalkableNeighbour(direction.x, direction.z, _unitProps, _neighbours); } //Forced neighbours? The left/down is as seen from a normal view of the grid, i.e. not seen from the direction of movement (well direction left corner diagonal) var nLeft = current.GetNeighbour(-direction.x, 0); if (nLeft != null && !nLeft.isWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(-direction.x, direction.z, _unitProps, _neighbours); } var nDown = current.GetNeighbour(0, -direction.z); if (nDown != null && !nDown.isWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(direction.x, -direction.z, _unitProps, _neighbours); } } else { if (nTop && nRight) { current.TryGetWalkableNeighbour(direction.x, direction.z, _unitProps, _neighbours); } } } else { //Natural neighbour current.TryGetWalkableNeighbour(direction.x, 0, _unitProps, _neighbours); //Forced neighbours? if (_cutCorners) { var nUp = current.GetNeighbour(0, 1); if (nUp != null && !nUp.isWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(direction.x, 1, _unitProps, _neighbours); } var nDown = current.GetNeighbour(0, -1); if (nDown != null && !nDown.isWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(direction.x, -1, _unitProps, _neighbours); } } else { var nUpBack = current.GetNeighbour(-direction.x, 1); if (nUpBack != null && !nUpBack.isWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(0, 1, _unitProps, _neighbours); current.TryGetWalkableNeighbour(direction.x, 1, _unitProps, _neighbours); } var nDownBack = current.GetNeighbour(-direction.x, -1); if (nDownBack != null && !nDownBack.isWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(0, -1, _unitProps, _neighbours); current.TryGetWalkableNeighbour(direction.x, -1, _unitProps, _neighbours); } } } } else { //Portals return Vector3.zero as the direction, and for those we need to start over on the new grid. if (direction.z == 0) { current.GetWalkableNeighbours(_neighbours, _unitProps, _cutCorners, false); return; } //Natural neighbour current.TryGetWalkableNeighbour(0, direction.z, _unitProps, _neighbours); //Forced neighbours? The left/right is as seen from a normal view of the grid, i.e. not seen from the direction of movement (well direction bottom up) if (_cutCorners) { var nLeft = current.GetNeighbour(-1, 0); if (nLeft != null && !nLeft.isWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(-1, direction.z, _unitProps, _neighbours); } var nRight = current.GetNeighbour(1, 0); if (nRight != null && !nRight.isWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(1, direction.z, _unitProps, _neighbours); } } else { var nLeftDown = current.GetNeighbour(-1, -direction.z); if (nLeftDown != null && !nLeftDown.isWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(-1, 0, _unitProps, _neighbours); current.TryGetWalkableNeighbour(-1, direction.z, _unitProps, _neighbours); } var nRightDown = current.GetNeighbour(1, -direction.z); if (nRightDown != null && !nRightDown.isWalkableFromAllDirections(_unitProps)) { current.TryGetWalkableNeighbour(1, 0, _unitProps, _neighbours); current.TryGetWalkableNeighbour(1, direction.z, _unitProps, _neighbours); } } } }
/// <summary> /// Gets the walkable successors of the specified node. /// </summary> /// <param name="current">The current node.</param> /// <param name="successorArray">The array to fill with successors.</param> /// <returns>All walkable successors of the node.</returns> protected virtual void GetWalkableSuccessors(IPathNode current, DynamicArray<IPathNode> successorArray) { current.GetWalkableNeighbours(successorArray, _unitProps, _cutCorners, _preventDiagonalMoves); }