/// <summary> /// /// </summary> /// <param name="gridSize"></param> /// <param name="additive"></param> /// <param name="interval"></param> public NavMeshNodeContainer(Vector2Int gridSize, Vector2 additive, float interval) { _nodes = new List <List <NavMeshNode> >(gridSize.x); for (var i = 0; i < gridSize.x; ++i) { var row = new List <NavMeshNode>(gridSize.y); for (var j = 0; j < gridSize.y; ++j) { var node = new NavMeshNode { node = new AStarSharp.Node(new System.Numerics.Vector2(i, j), true), worldPosition = new Vector2((i - additive.x) * interval, (j - additive.y) * interval), gridPosition = new Vector2Int(i, j), walkable = true, }; row.Add(node); } _nodes.Add(row); } this.gridSize = gridSize; _additive = additive; _interval = interval; }
/// <summary> /// /// </summary> /// <param name="startNode"></param> /// <param name="targetNode"></param> /// <returns></returns> public IReadOnlyList <Vector2> FindPath(NavMeshNode startNode, NavMeshNode targetNode) { const float additiveX = GameConstants.SceneWidth / 2.0f / RayInterval; const float additiveY = GameConstants.SceneHeight / 2.0f / RayInterval; var path = new List <Vector2>(); if (_astar == null) { return(path); } var nodeStack = _astar.FindPath( new System.Numerics.Vector2(startNode.gridPosition.x, startNode.gridPosition.y), new System.Numerics.Vector2(targetNode.gridPosition.x, targetNode.gridPosition.y)); if (nodeStack == null) { return(path); } foreach (var node in nodeStack) { path.Add(new Vector2((node.Position.X - additiveX) * RayInterval, (node.Position.Y - additiveY) * RayInterval)); } path.Add(targetNode.worldPosition); return(path); }
/// <summary> /// /// </summary> /// <param name="target"></param> /// <returns></returns> private NavMeshNode GetClosestNode(Vector2 target) { int xDim; int yDim; var node = navMesh.nodeContainer.GetNodeAt(target.x, target.y, out xDim, out yDim); if (node == null) { return(null); } var step = 0; while (node == null || !node.walkable) { ++step; NavMeshNode closestNode = null; float closestDistance = float.MaxValue; for (var i = -1; i <= 1; ++i) { for (var j = -1; j <= 1; ++j) { if (i == 0 && j == 0) { continue; } if (TryGetNode(xDim + (step * i), yDim + (step * j), out node)) { var distance = Vector2.Distance(target, node.worldPosition); if (distance < closestDistance) { closestDistance = distance; closestNode = node; } } } } if (closestNode != null) { node = closestNode; break; } } return(node); }
/// <summary> /// /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="node"></param> /// <returns></returns> private bool TryGetNode(int x, int y, out NavMeshNode node) { node = null; if (x < 0 || y < 0) { return(false); } if (x >= navMesh.nodeContainer.nodes.Count) { return(false); } if (y >= navMesh.nodeContainer.nodes[x].Count) { return(false); } node = navMesh.nodeContainer.GetNodeAt(x, y); return(node.walkable); }