private Dictionary <string, Vector3> PopulateWithShape(MazeFrame mazeFrame, float fracConnSpace, int nNodesPerConnectionObj, string baseShape, string connShape) { // Set space allowed for connection as fraction of average connection length between nodes fracConnSpace = Mathf.Clamp01(fracConnSpace); float connSpace = (mazeFrame.Scale[0] + mazeFrame.Scale[1] + mazeFrame.Scale[2]) / 3 * fracConnSpace; // Prep storing of object center line nodes //int nNodesPerConnectionObj = 3; int nNodesPerBaseObj = 2; int nNodes = (mazeFrame.NumberOfConnections() * nNodesPerBaseObj) + (mazeFrame.NumberOfUniquePairwiseConnections() * nNodesPerConnectionObj); Dictionary <string, Vector3> objCenterLineNodes = new Dictionary <string, Vector3>(nNodes); // Load prefabs and set parent for game objects GameObject prefabCyl = Resources.Load("Prefabs/" + baseShape) as GameObject; GameObject prefabCylConn = Resources.Load("Prefabs/" + connShape) as GameObject; GameObject mazeObjects = new GameObject("mazeObjects"); mazeObjects.transform.position = Vector3.zero; mazeObjects.transform.rotation = Quaternion.identity; mazeObjects.AddComponent <MeshFilter>(); mazeObjects.AddComponent <MeshRenderer>(); mazeObjects.GetComponent <MeshRenderer>().material = prefabCyl.GetComponent <MeshRenderer>().sharedMaterial; // First, go through each node and built appropriately bended connections foreach (MazeNode node in mazeFrame.Nodes) { // Check whether we're at a dead end if (node.ConnectedNeighbors.Count <= 1) { continue; } // Place connection object and pass center line nodes to main dictionary Dictionary <string, Vector3> newCenterLineNodes = PlaceShapeConnectionAtJunction(mazeObjects, node, prefabCylConn, connSpace, nNodesPerConnectionObj); Dictionary <string, Vector3> .KeyCollection keys = newCenterLineNodes.Keys; foreach (string key in keys) { objCenterLineNodes.Add(key, newCenterLineNodes[key]); } // Increment global counter MazeObjectsPlaced++; } // Then, build the base connections (store visit record) Dictionary <string, bool> isVisited = new Dictionary <string, bool>(mazeFrame.Nodes.Count); foreach (MazeNode nd in mazeFrame.Nodes) { isVisited.Add(nd.Identifier, false); } foreach (MazeNode node in mazeFrame.Nodes) { foreach (MazeNode neighbor in node.ConnectedNeighbors) { // Check whether all connections involving this neighbor have been built already if (isVisited[neighbor.Identifier]) { continue; } // set object properties Vector3 position = (node.Position + neighbor.Position) / 2; float scale = Vector3.Distance(node.Position, neighbor.Position); scale = scale - connSpace; Quaternion rot = prefabCyl.transform.rotation * Quaternion.FromToRotation(Vector3.forward, Vector3.Normalize(neighbor.Position - node.Position)); // Check dead end ends/start/end if (node.ConnectedNeighbors.Count == 1 || node.Identifier == "start" || node.Identifier == "end") { position = position + ((node.Position - neighbor.Position).normalized * (connSpace / 4)); scale = scale + (connSpace / 2); } if (neighbor.ConnectedNeighbors.Count == 1 || neighbor.Identifier == "start" || neighbor.Identifier == "end") { position = position + ((neighbor.Position - node.Position).normalized * (connSpace / 4)); scale = scale + (connSpace / 2); } // Place object and set scale GameObject cyl = Object.Instantiate(prefabCyl, position, rot, mazeObjects.transform); cyl.transform.localScale = new Vector3(cyl.transform.localScale.x, cyl.transform.localScale.y, cyl.transform.localScale.z * scale); cyl.name = "base-" + node.Identifier + "-" + neighbor.Identifier; cyl.AddComponent <MeshCollider>(); cyl.GetComponent <MeshCollider>().convex = true; // Add two nodes (start/end) to storage with naming scheme: base-<nodeid>-<neighid> // If on dead end ends/start/end --> nodes at the extremes // If not --> shift nodes from the extremes to the center (as the conn nodes start at the extremes as well Vector3 nodeGravPos; Vector3 neighbGravPos; if (node.ConnectedNeighbors.Count == 1 || node.Identifier == "start" || node.Identifier == "end") { nodeGravPos = position + (node.Position - neighbor.Position).normalized * (scale / 2); } else { nodeGravPos = position + (node.Position - neighbor.Position).normalized * (scale / 4); } if (neighbor.ConnectedNeighbors.Count == 1 || neighbor.Identifier == "start" || neighbor.Identifier == "end") { neighbGravPos = position + (neighbor.Position - node.Position).normalized * (scale / 2); } else { { neighbGravPos = position + (neighbor.Position - node.Position).normalized * (scale / 4); } } objCenterLineNodes.Add("base-" + node.Identifier + "-" + neighbor.Identifier, nodeGravPos); objCenterLineNodes.Add("base-" + neighbor.Identifier + "-" + node.Identifier, neighbGravPos); } // Set current node as visisted isVisited[node.Identifier] = true; // Increment global counter MazeObjectsPlaced++; } //Utilities.MergeChildrenOfParent(mazeObjects); return(objCenterLineNodes); }