private void initBystanderNavGraph(Dictionary<string,Rect> para_worldBoundsLookup, Transform para_debugPrefab) { Dictionary<string,Rect> worldBoundsLookup = para_worldBoundsLookup; bystanderNavGraph = new BasicNavGraph(); GameObject lwalkwayObj = GameObject.Find("LeftWalk"); float graphZPos = lwalkwayObj.transform.position.z; Rect leftWalkwayWorld = worldBoundsLookup["LeftWalkway"]; Vector3 lw_topMid = new Vector3(leftWalkwayWorld.x + (leftWalkwayWorld.width/2f),leftWalkwayWorld.y,graphZPos); Vector3 lw_botMid = new Vector3(lw_topMid.x,leftWalkwayWorld.y - (leftWalkwayWorld.height),graphZPos); Rect topWalkwayWorld = worldBoundsLookup["TopWalkway"]; Vector3 tw_leftMid = new Vector3(topWalkwayWorld.x,topWalkwayWorld.y - (topWalkwayWorld.height/2f),graphZPos); Vector3 tw_rightMid = new Vector3(topWalkwayWorld.x + topWalkwayWorld.width,tw_leftMid.y,graphZPos); Rect rightWalkwayWorld = worldBoundsLookup["RightWalkway"]; Vector3 rw_topMid = new Vector3(rightWalkwayWorld.x + (rightWalkwayWorld.width/2f),rightWalkwayWorld.y,graphZPos); Vector3 rw_botMid = new Vector3(rw_topMid.x,rightWalkwayWorld.y - rightWalkwayWorld.height,graphZPos); Rect bottomWalkwayWorld = worldBoundsLookup["BottomWalkway"]; Rect bottomEntranceWorld = worldBoundsLookup["BottomEntrance"]; List<Vector3> bottomWalkwayPoints = new List<Vector3>(); List<Vector3> bottomEntrancePoints = new List<Vector3>(); float entranceSpacing = 2; int numEntrances = (int) ((bottomEntranceWorld.width - entranceSpacing) / entranceSpacing); Vector3 nxtBottomWalkwayPt = new Vector3(bottomWalkwayWorld.x + entranceSpacing,bottomWalkwayWorld.y - (bottomWalkwayWorld.height/2f),graphZPos); Vector3 nxtBottomEntrancePt = new Vector3(bottomEntranceWorld.x + entranceSpacing,bottomEntranceWorld.y - ( Random.Range(0,2)),graphZPos); //Vector3 nxtBottomEntrancePt = new Vector3(bottomEntranceWorld.x + entranceSpacing,bottomEntranceWorld.y - (bottomEntranceWorld.height + Random.Range(2,6)),graphZPos); for(int i=0; i<numEntrances; i++) { bottomWalkwayPoints.Add(nxtBottomWalkwayPt); bottomEntrancePoints.Add(nxtBottomEntrancePt); nxtBottomWalkwayPt.x += entranceSpacing; nxtBottomEntrancePt.x += entranceSpacing; nxtBottomEntrancePt.y = bottomEntranceWorld.y - (bottomEntranceWorld.height + 1);//Random.Range(2,6)); } Vector3[] posList = new Vector3[6] { lw_botMid, lw_topMid, tw_leftMid, tw_rightMid, rw_topMid, rw_botMid }; int nodeTicketID = 0; for(int i=0; i<posList.Length; i++) { bystanderNavGraph.addNode(new WorldNode(nodeTicketID,1,posList[i])); if(i > 0) { bystanderNavGraph.addEdge(nodeTicketID-1,nodeTicketID,new NavEdge(new int[2] { (nodeTicketID-1), nodeTicketID },1)); } nodeTicketID++; } cornerNodeIDs = new List<int>() { 0,2,4,5 }; topNodes = new List<int>() { 2,3 }; leftNodes = new List<int>() { 0,1 }; rightNodes = new List<int>() { 4,5 }; bottomWalkwayNodeIDs = new List<int>(); for(int i=0; i<bottomWalkwayPoints.Count; i++) { bystanderNavGraph.addNode(new WorldNode(nodeTicketID,1,bottomWalkwayPoints[i])); bottomWalkwayNodeIDs.Add(nodeTicketID); if(i > 0) { bystanderNavGraph.addEdge(nodeTicketID-1,nodeTicketID,new NavEdge(new int[2] { (nodeTicketID-1), nodeTicketID },1)); } nodeTicketID++; } bystanderNavGraph.addEdge(bottomWalkwayNodeIDs[0],0,new NavEdge(new int[2] { bottomWalkwayNodeIDs[0], 0 },1)); bystanderNavGraph.addEdge(bottomWalkwayNodeIDs[bottomWalkwayNodeIDs.Count-1],5,new NavEdge(new int[2] { bottomWalkwayNodeIDs[bottomWalkwayNodeIDs.Count-1], 5 },1)); bottomEntranceNodeIDs = new List<int>(); for(int i=0; i<bottomEntrancePoints.Count; i++) { bystanderNavGraph.addNode(new WorldNode(nodeTicketID,2,bottomEntrancePoints[i])); bottomEntranceNodeIDs.Add(nodeTicketID); bystanderNavGraph.addEdge(nodeTicketID,bottomWalkwayNodeIDs[i],new NavEdge(new int[2] { nodeTicketID, bottomWalkwayNodeIDs[i]},1)); nodeTicketID++; } areas = new Dictionary<string, Rect>(); areas.Add("L",leftWalkwayWorld); areas.Add("T",topWalkwayWorld); areas.Add("R",rightWalkwayWorld); GameObject navGraphRender = NavGraphUnityUtils.renderNavGraph("MPBystanderNavGraphRender",bystanderNavGraph,para_debugPrefab); navGraphRender.SetActive(false); }
// Nodes are added by moving a single cell. // Edges are initially one length edges. // Post processing can reduce the number of nodes. // // # # # // # X # // # # # // // X = Node checking. // # = Neighbour/Graph Edge checking. // public NavGraph constructGraph() { BasicNavGraph retGraph = new BasicNavGraph(); int nxtNodeID = 0; int nxtEdgeID = 0; Dictionary<string,int> coordToNodeIDMap = new Dictionary<string,int>(); Texture2D mapImg = Resources.Load<Texture2D>(imgPath); if(mapImg != null) { Color[] pixels = mapImg.GetPixels(); for(int r=0; r<mapImg.height; r++) { for(int c=0; c<mapImg.width; c++) { Color tmpPixel = pixels[(r * mapImg.width) + c]; if(tmpPixel.Equals(traversibleColor)) { // Add new node. ImgNode nwNode = new ImgNode(nxtNodeID,1,new int[2] { c,r }); retGraph.addNode(nwNode); coordToNodeIDMap.Add((""+c+"-"+r),nwNode.getNodeID()); nxtEdgeID++; // Get valid neighbourhood pixels. List<Color> neighbourhoodPixels = new List<Color>(); List<int[]> reqNPixCoords = new List<int[]>(); reqNPixCoords.Add(new int[2]{(c-1),(r-1)}); reqNPixCoords.Add(new int[2]{(c),(r-1)}); reqNPixCoords.Add(new int[2]{(c+1),(r-1)}); reqNPixCoords.Add(new int[2]{(c-1),(r)}); List<int> validCoordIndexList = new List<int>(); for(int k=0; k<reqNPixCoords.Count; k++) { int[] tmpCoords = reqNPixCoords[k]; if((tmpCoords[0] >= 0)&&(tmpCoords[0] < mapImg.width) &&(tmpCoords[1] >= 0)&&(tmpCoords[1] < mapImg.height)) { // Valid coords. validCoordIndexList.Add(k); neighbourhoodPixels.Add( pixels[(tmpCoords[1] * mapImg.width) + tmpCoords[0]] ); } } // Check for neighbours and create edges. (NavGraph will handle the internal creation of neighbour references, just run addEdge). for(int k=0; k<validCoordIndexList.Count; k++) { if(neighbourhoodPixels[k].Equals(traversibleColor)) { int[] neighbourCoords = reqNPixCoords[k]; int neighbourID = coordToNodeIDMap[(""+neighbourCoords[0]+"-"+neighbourCoords[1])]; retGraph.addEdge(nwNode.getNodeID(),neighbourID,new NavEdge(new int[2] {nwNode.getNodeID(),neighbourID},1)); } } } } } } return retGraph; }
private void initBlankNavGraph() { if(firstLevel) { // Create the datastructure. boardNavGraph = new BasicNavGraph(); cellNameToNodeIDMap = new Dictionary<string,int>(); nodeIDToCellNameMap = new Dictionary<int,string>(); int boardWidth_inColumns = boardSize[0]; int boardHeight_inRows = boardSize[1]; int cellID = 0; GameObject hexBoardObj = GameObject.Find("HexBoard"); for(int c=0; c<boardWidth_inColumns; c++) { int numOfRowsForColumn = boardHeight_inRows; bool isOddColumn = false; if((c%2) != 0) { numOfRowsForColumn = boardHeight_inRows-1; isOddColumn = true; } for(int r=0; r<numOfRowsForColumn; r++) { Transform reqCell = hexBoardObj.transform.FindChild("Cell("+c+","+r+")"); if(reqCell != null) { WorldNode nwNavNode = new WorldNode(cellID,1,reqCell.position); boardNavGraph.addNode(nwNavNode); cellNameToNodeIDMap.Add(reqCell.name,cellID); nodeIDToCellNameMap.Add(cellID,reqCell.name); // Get potential neighbours. List<int[]> potentialNeighbourCoords = new List<int[]>(); potentialNeighbourCoords.Add(new int[2] {c,r-1}); potentialNeighbourCoords.Add(new int[2] {c,r+1}); if(! isOddColumn) { potentialNeighbourCoords.Add(new int[2] {c-1,r-1}); potentialNeighbourCoords.Add(new int[2] {c-1,r}); //potentialNeighbourCoords.Add(new int[2] {c+1,r-1}); //potentialNeighbourCoords.Add(new int[2] {c+1,r}); } else { potentialNeighbourCoords.Add(new int[2] {c-1,r}); potentialNeighbourCoords.Add(new int[2] {c-1,r+1}); //potentialNeighbourCoords.Add(new int[2] {c+1,r}); //potentialNeighbourCoords.Add(new int[2] {c+1,r+1}); } for(int i=0; i<potentialNeighbourCoords.Count; i++) { int[] tmpCoords = potentialNeighbourCoords[i]; string potentialNeighbourName = "Cell("+tmpCoords[0]+","+tmpCoords[1]+")"; Transform reqNeighbourCell = hexBoardObj.transform.FindChild(potentialNeighbourName); if(reqNeighbourCell != null) { if(cellNameToNodeIDMap.ContainsKey(potentialNeighbourName)) { int neighbourNodeID = cellNameToNodeIDMap[potentialNeighbourName]; boardNavGraph.addEdge(cellID,neighbourNodeID,new NavEdge(new int[2] {cellID,neighbourNodeID},1)); } } } cellID++; } } } GameObject navRendering = NavGraphUnityUtils.renderNavGraph("MPBoardNavGraphRender",boardNavGraph,debugPrefab); navRendering.SetActive(false); } else { // If not first level. Simply reset all node types to type 1: i.e. reachable type. List<int> nodeKeys = boardNavGraph.getAllNodeKeys(); for(int i=0; i<nodeKeys.Count; i++) { boardNavGraph.setNodeType(nodeKeys[i],1); } } }
// Nodes are added by moving a single cell. // Edges are initially one length edges. // Post processing can reduce the number of nodes. // // # # # // # X # // # # # // // X = Node checking. // # = Neighbour/Graph Edge checking. // public NavGraph constructGraph() { BasicNavGraph retGraph = new BasicNavGraph(); int nxtNodeID = 0; //int nxtEdgeID = 0; Dictionary<string,int> coordToNodeIDMap = new Dictionary<string,int>(); Texture2D mapImg = Resources.Load<Texture2D>(imgPath); if(mapImg != null) { // NOTE: UNITY RETURNS THIS ARRAY WHICH STARTS WITH ROWS BOTTOM-UP. pixels = mapImg.GetPixels(); for(int r=0; r<mapImg.height; r++) { for(int c=0; c<mapImg.width; c++) { // (pixels.Length-mapImg.width) - This is to navigate the image top down while still abiding with Unity's returned pixel array which goes bottom up. Color tmpPixel = pixels[(pixels.Length - mapImg.width) - (r * mapImg.width) + c]; if(tmpPixel.Equals(traversibleColor)) { // Add new node. WorldNode nwNode = new WorldNode(nxtNodeID,1, new Vector3((worldGProp.x + (worldGProp.cellWidth/2f)) + (worldGProp.cellWidth * c), (worldGProp.y - (worldGProp.cellWidth/2f)) - (worldGProp.cellHeight * r), worldGProp.z)); retGraph.addNode(nwNode); coordToNodeIDMap.Add((""+c+"-"+r),nwNode.getNodeID()); nxtNodeID++; // Get valid neighbourhood pixels. List<Color> neighbourhoodPixels = new List<Color>(); List<int[]> reqNPixCoords = new List<int[]>(); //reqNPixCoords.Add(new int[2]{(c-1),(r-1)}); reqNPixCoords.Add(new int[2]{(c),(r-1)}); //reqNPixCoords.Add(new int[2]{(c+1),(r-1)}); reqNPixCoords.Add(new int[2]{(c-1),(r)}); List<int> validCoordIndexList = new List<int>(); for(int k=0; k<reqNPixCoords.Count; k++) { int[] tmpCoords = reqNPixCoords[k]; if((tmpCoords[0] >= 0)&&(tmpCoords[0] < mapImg.width) &&(tmpCoords[1] >= 0)&&(tmpCoords[1] < mapImg.height)) { // Valid coords. validCoordIndexList.Add(k); neighbourhoodPixels.Add( pixels[(pixels.Length - mapImg.width) - (tmpCoords[1] * mapImg.width) + tmpCoords[0]] ); } } // Check for neighbours and create edges. (NavGraph will handle the internal creation of neighbour references, just run addEdge). for(int k=0; k<validCoordIndexList.Count; k++) { if(neighbourhoodPixels[k].Equals(traversibleColor)) { int[] neighbourCoords = reqNPixCoords[k]; int neighbourID = coordToNodeIDMap[(""+neighbourCoords[0]+"-"+neighbourCoords[1])]; retGraph.addEdge(nwNode.getNodeID(),neighbourID,new NavEdge(new int[2] {nwNode.getNodeID(),neighbourID},1)); } } } } } } return retGraph; }