Пример #1
0
	public void CreateGrid (SimpleNode[][] nodes) {
		if (nodes.Length < 1) {
			Debug.LogError ("Make sure you use at least one grid");
		}
		
		
			
		Grid[] allGrids = new Grid[nodes.Length];
		for (int i=0;i<allGrids.Length;i++) {
			allGrids[i] = new Grid ();
			allGrids[i].width = nodes[i].Length;
			allGrids[i].depth = 1;
			
			if (allGrids[i].width < 1) {
				Debug.LogError ("Make sure you use at least one node for each grid");
				return;
			}
		}
		
		staticNodes = new Node[allGrids.Length][,];
		totalNodeAmount = 0;
		
		for (int i=0;i<allGrids.Length;i++) {
			Grid grid = allGrids[i];
			staticNodes[i] = new Node [grid.width,grid.depth];
			totalNodeAmount+= grid.width*grid.depth;
		}
		
		for (int y=0;y<allGrids.Length;y++) {
			
			SimpleNode[] gridNodes = nodes[y];
			
			for (int x=0;x<gridNodes.Length;x++) {
				Node node = new Node ();
				node.pos = new Int3(x,y,0);
				gridNodes[x].pos = node.pos;
				node.vectorPos = gridNodes[x].vectorPos;
				staticNodes[y][x,0] = node;
			}
		}
		
		for (int y=0;y<allGrids.Length;y++) {
			Grid grid = allGrids[y];
			
			SimpleNode[] gridNodes = nodes[y];
			
			for (int x=0;x<gridNodes.Length;x++) {
				Node node = staticNodes[y][x,0];
				
				node.connections = new Connection[gridNodes[x].neighbours.Length];
				
				for (int i=0;i<node.connections.Length;i++) {
					Node neighbour = GetNode (gridNodes[x].neighbours[i].pos);
					int cost = gridNodes[x].costs == null ? (int)(Vector3.Distance (neighbour.vectorPos,node.vectorPos)*100) : gridNodes[x].costs[i];
					float angle = gridNodes[x].angles == null ? 0 : gridNodes[x].angles[i];
					
					node.connections[i] = new Connection (neighbour,cost,angle,true);
				}
				
				node.GenerateEnabledConnections ();
			}
			
			
			Bounds b = new Bounds (staticNodes[y][0,0].vectorPos,Vector3.zero);
			for (int x=0;x<gridNodes.Length;x++) {
				b.Encapsulate (staticNodes[y][x,0].vectorPos);
			}
			
			b.extents += Vector3.one * boundsMargin;
			
			grid.globalWidth = b.size.x;
			grid.globalDepth = b.size.z;
			grid.globalHeight = b.size.y;
			
			grid.globalOffset = (b.center-b.extents);
		}
		grids = allGrids;
		FloodFillAll ();
		
		binaryHeap = new BinaryHeap (Mathf.CeilToInt (totalNodeAmount*heapSize));
	}
Пример #2
0
	public void GenerateNavmesh (Vector3[] points) {
		Bounds bounds = new Bounds ();
		for (int i=0;i<points.Length;i++) {
			bounds.Encapsulate (points[i]);
		}
		
		bounds.extents += Vector3.one * boundsMargin;
		
		Grid grid = new Grid (20);
		grids = new Grid[1] {grid};
		grid.width = points.Length;
		grid.depth = 1;
		grid.globalWidth = Mathf.CeilToInt (bounds.size.x);
		grid.globalDepth = Mathf.CeilToInt (bounds.size.z);
		grid.globalHeight = Mathf.CeilToInt (bounds.size.y);
		grid.nodeSize = 1;
		grid.offset = bounds.center-bounds.extents;
		//grid.nodeSize = 1;
		
		staticNodes = new Node[1][,];
		staticNodes[0] = new Node [grid.width,grid.depth];
		
		totalNodeAmount = grid.depth * grid.width;
		//for (int z=0;z<grid.depth;z++) {//Depth
		for (int x=0;x<grid.width;x++) {//Width
			Node node = new Node ();
			node.pos = new Int3 (x,0,0);
			node.vectorPos = points[x];
			
			staticNodes[0][x,0] = node;
		}
		
		for (int x=0;x<grid.width;x++) {//Width
			Node node = staticNodes[0][x,0];
			for (int i=0;i<grid.width;i++) {//Width
				Node otherNode = staticNodes[0][i,0];
				if (otherNode.vectorPos == node.vectorPos && otherNode != node) {
					//Debug.LogWarning ("Similar "+x+" "+i);
				}
			}
		}
		
		ApplyEnablerLinks ();
		
		//Loop through all nodes
		for (int x=0;x<grid.width;x++) {//Width
			Node node = staticNodes[0][x,0];
			
			if (!node.walkable) {
				node.connections = new Connection[0];
				node.GenerateEnabledConnections ();
				continue;
			}
			
			ArrayList connections = new ArrayList ();
			
			//Loop through all nodes and see which of them qualifies for being neighbours
			for (int i=0;i<grid.width;i++) {//Width
				Node otherNode = staticNodes[0][i,0];
				
				//Limit nodes from being at the same position and from being to far away from each other on the Y axis
				if (otherNode.vectorPos == node.vectorPos || Mathf.Abs (node.vectorPos.y-otherNode.vectorPos.y) > yLimit || !otherNode.walkable) {
					continue;
				}
				if (otherNode == node) {
					continue;
				}
				
				RaycastHit hit;
				if (Physics.Linecast (node.vectorPos,otherNode.vectorPos,out hit,boundsRayHitMask) || Physics.Linecast (otherNode.vectorPos,node.vectorPos,out hit,boundsRayHitMask)) {
					continue;
				} else {
					float dist = (node.vectorPos-otherNode.vectorPos).sqrMagnitude;
					if (dist <= neighbourDistanceLimit*neighbourDistanceLimit) {
						
						//This node qualifies for being a neighbour, so now we create a connection to it
						int cost = Mathf.RoundToInt (Mathf.Sqrt(dist)*100);
						Vector3 dir = otherNode.vectorPos-node.vectorPos;
						Vector3 dir2 = dir;
						dir2.y = 0;
						float angle = Vector3.Angle (dir,dir2);
						connections.Add (new Connection(otherNode,cost,angle,true));
					}
				}
			}
			
			node.connections = connections.ToArray (typeof(Connection)) as Connection[];
			
			node.GenerateEnabledConnections ();
		}
		
		ApplyLinks ();
		FloodFillAll ();
		
	}
Пример #3
0
	//This is to be used only with Grid-like navmeshes!
	public void RecalcNeighbours (Node node) {
		
		int x = node.pos.x;
		int y = node.pos.y;
		int z = node.pos.z;
		
		Grid grid = grids[y];
		
		int topLeftCut = 0;
		int topRightCut = 0;
		int bottomLeftCut = 0;
		int bottomRightCut = 0;
		
		
		//Add the node left of this node to it's neighbourlist if it is walkable
		if (x != 0 && (isNeighbours==IsNeighbour.Eight || isNeighbours==IsNeighbour.Four)) {
			node.connections[3].endNode = GetNode(x-1,y,z);
			node.connections[3].enabled = GetNode(x-1,y,z).walkable && node.connections[3].angle < staticMaxAngle;
			if (node.connections[3].enabled) {
				topLeftCut++;
				bottomLeftCut++;
			}
		}
		
		if (x != grid.width-1 && (isNeighbours==IsNeighbour.Eight || isNeighbours==IsNeighbour.Four)) {
			node.connections[4].endNode = GetNode(x+1,y,z);
			node.connections[4].enabled = GetNode(x+1,y,z).walkable && node.connections[4].angle < staticMaxAngle;
			if (node.connections[4].enabled) {
				topRightCut ++;
				bottomRightCut ++;
			}
		}
		
		if (z != 0) {
			if ((isNeighbours==IsNeighbour.Eight || isNeighbours==IsNeighbour.Four)) {
				node.connections[6].endNode = GetNode(x,y,z-1);
				node.connections[6].enabled = GetNode(x,y,z-1).walkable && node.connections[6].angle < staticMaxAngle;
				if (node.connections[6].enabled) {
					bottomLeftCut ++;
					bottomRightCut ++;
				}
			}
			
			if (x != 0 && isNeighbours==IsNeighbour.Eight) {
				node.connections[5].endNode = GetNode(x-1,y,z-1);
				node.connections[5].enabled = GetNode(x-1,y,z-1).walkable && node.connections[5].angle < staticMaxAngle && (bottomLeftCut==2 || !dontCutCorners);
			}
			
			if (x != grid.width-1 && isNeighbours==IsNeighbour.Eight) {
				node.connections[7].endNode = GetNode(x+1,y,z-1);
				node.connections[7].enabled = GetNode(x+1,y,z-1).walkable && node.connections[7].angle < staticMaxAngle && (bottomRightCut==2 || !dontCutCorners);
			}
		}
		
		if (z != grid.depth-1) {
			
			if ((isNeighbours==IsNeighbour.Eight || isNeighbours==IsNeighbour.Four)) {
				node.connections[1].endNode = GetNode(x,y,z+1);
				node.connections[1].enabled = GetNode(x,y,z+1).walkable && node.connections[1].angle < staticMaxAngle;
				if (node.connections[1].enabled) {
					topLeftCut++;
					topRightCut++;
				}
			}
			
			if (x != 0 && isNeighbours==IsNeighbour.Eight) {
				node.connections[0].endNode = GetNode(x-1,y,z+1);
				node.connections[0].enabled = GetNode(x-1,y,z+1).walkable && node.connections[0].angle < staticMaxAngle && (topLeftCut==2 || !dontCutCorners);
			}
			
			if (x != grid.width-1 && isNeighbours==IsNeighbour.Eight) {
				node.connections[2].endNode = GetNode(x+1,y,z+1);
				node.connections[2].enabled = GetNode(x+1,y,z+1).walkable && node.connections[2].angle < staticMaxAngle && (topRightCut==2 || !dontCutCorners);
			}
		}
		
		node.GenerateEnabledConnections ();
	}