/// <summary>
 /// 
 /// </summary>
 /// <param name="searchParameters"></param>
 public PathFinder(SearchParameters searchParameters)
 {
     _searchParameters = searchParameters;
     InitializeNodes(searchParameters.Map);
     _startNode = _nodes[(int)searchParameters.StartLocation.x, (int)searchParameters.StartLocation.y];
     _startNode.State = Node.NodeState.Open;
     _endNode = _nodes[(int)searchParameters.EndLocation.x, (int)searchParameters.EndLocation.y];
 }
示例#2
0
        public Grid(Terrain terrain, float sample, float heightCost)
        {
            _terrain = terrain;

            _worldPosition = terrain.GetPosition();
            var width = (int)terrain.terrainData.size.x;
            var height = (int)terrain.terrainData.size.z;

            SampledWidth = (int)Mathf.Ceil(width / sample);
            SampledHeight = (int)Mathf.Ceil(height / sample);
            _sample = sample;
            _heightCost = heightCost;
            InternalGrid = new Node[SampledWidth, SampledHeight];
            InternalGridWithUnwalkable = new Node[SampledWidth, SampledHeight];
            //Build the Grid [width,height] --> O(n^2)
            InitGrid();
            InitGridWithUnWalkable();

            //Initialize the edges/neighboots --> O(n^2)
            InitEdges();
            InitEdgesWithUnWalkable();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="currentNode"></param>
        /// <returns></returns>
        private bool Search(Node currentNode)
        {
            currentNode.State = Node.NodeState.Closed;
            List<Node> nextNodes = GetAdjacentWalkableNodes(currentNode);

            nextNodes.Sort((node1, node2) => node1.F.CompareTo(node2.F));
            foreach (var nextNode in nextNodes)
            {
                if (nextNode.Location == _endNode.Location)
                {
                    return true;
                }
                if (Search(nextNode))
                {
                    return true;
                }
            }
            return false;
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="map"></param>
 private void InitializeNodes(bool[,] map)
 {
     _width = map.GetLength(0);
     _height = map.GetLength(1);
     _nodes = new Node[_width, _height];
     for (int y = 0; y < _height; y++)
     {
         for (int x = 0; x < _width; x++)
         {
             _nodes[x, y] = new Node(x, y, map[x, y], _searchParameters.EndLocation);
         }
     }
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fromNode"></param>
        /// <returns></returns>
        private List<Node> GetAdjacentWalkableNodes(Node fromNode)
        {
            List<Node> walkableNodes = new List<Node>();
            IEnumerable<Vector2> nextLocations = GetAdjacentLocations(fromNode.Location);

            foreach (var location in nextLocations)
            {
                int x = (int)location.x;
                int y = (int)location.y;

                if (x < 0 || x >= _width || y < 0 || y >= _height)
                {
                    continue;
                }

                Node node = _nodes[x, y];
                if (!node.IsWalkable)
                {
                    continue;
                }
                if (node.State == Node.NodeState.Closed)
                {
                    continue;
                }
                if (node.State == Node.NodeState.Open)
                {
                    float traversalCost = Node.GetTraversalCost(node.Location, node.ParentNode.Location);
                    float gTemp = fromNode.G + traversalCost;
                    if (gTemp < node.G)
                    {
                        node.ParentNode = fromNode;
                        walkableNodes.Add(node);
                    }
                }
                else
                {
                    node.ParentNode = fromNode;
                    node.State = Node.NodeState.Open;
                    walkableNodes.Add(node);
                }
            }

            return walkableNodes;
        }
示例#6
0
        private void InitGridWithUnWalkable()
        {
            LayerMask mask = 1 << 2; //it's ignore raycast

            for (var i = 0; i < SampledWidth; i++)
            {
                for (var j = 0; j < SampledHeight; j++)
                {
                    var x = _sample * 0.5f * (2 * i + 1); //I calculate the center of each grid i * sample + sample / 2
                    var z = _sample * 0.5f * (2 * j + 1);
                    float attenuation = 0;
                    var pos = new Vector3(x, 0, z) + _worldPosition;

                    var terrainheight = _terrain.SampleHeight(pos);
                    pos.y = terrainheight;

                    RaycastHit hit;
                    var intersect = Physics.Raycast(pos + new Vector3(0, 10, 0), Vector3.down, out hit, Mathf.Infinity, ~mask);
                    if (intersect)
                    {
                        var colliderSize = hit.collider.bounds.size;
                        var colliderHeight = colliderSize.y;
                        attenuation = colliderHeight;
                    }

                    var cost = intersect ? int.MaxValue : 1;
                    attenuation = (terrainheight + attenuation);
                    var node = new Node(cost, attenuation, new Location(i, j), pos, isWalkable: !intersect);
                    InternalGridWithUnwalkable[i, j] = node;
                }
            }
        }
示例#7
0
        private IEnumerable<Node> FindNeighboors(Node node, int i, int j)
        {
            var neighboors = new List<Node>(4);

            foreach (var point in _directions)
            {
                if (0 > i + point.X || i + point.X >= SampledWidth || 0 > j + point.Y || j + point.Y >= SampledHeight)
                    continue;

                var neighNode = InternalGrid[i + point.X, j + point.Y];

                if (neighNode.IsWalkable)
                    neighboors.Add(neighNode);
            }

            return neighboors;
        }
示例#8
0
        /// <summary>
        /// Heuristics on the specified Node based on the Manhattan distance
        /// </summary>
        /// <param name="a">The Node a.</param>
        /// <param name="b">The goal Node b.</param>
        /// <returns></returns>
        private static float Heuristic(Node a, Node b)
        {
            var dx = Mathf.Abs(a.Position.x - b.Position.x);
            var dz = Mathf.Abs(a.Position.z - b.Position.z);
            var dy = Mathf.Abs(a.Position.y - b.Position.y);

            return 1.0f * (dx + dy + dz);
        }
示例#9
0
 public List<Vector3> ForceSearch(Node startN, Node endN, Node targetNode)
 {
     throw new NotImplementedException();
 }