// Check for new links inside the cluster public bool CheckNewLinks(List <Node> cluster, bool canCreateNew = true) { bool addedNewNodes = false; foreach (var node in cluster.ToArray()) { // The ToArray is to iterate over a copy of the list, and so we can add new items while iterating Vector3 tmp_dir = (node.position - position); float dist = tmp_dir.magnitude; if (CanSeeNode(node, dist, tmp_dir)) { // If we can see the node, link the 2 nodes together // // Uncoment theses 2 lines to keep the graph simple with big links. // // Will generate faster, but will be less precise for AI movement // AddLink(node, dist); // continue; // if dist > nodesMaxDistance, add in between nodes if (dist > NavigationGraph.maxLinkLength && dist < NavigationGraph.nodesMaxDistance && canCreateNew && false) // Disable this for now { int nb = (int)(dist / NavigationGraph.maxLinkLength); // compute nb of nodes to add Vector3 dir = (node.position - position).normalized; float intermediateDist = dist / (nb + 1); // distance between nodes Node prev = this; // Keep track of the previous node to add in between links while (nb > 0) { Vector3 pos = prev.position + dir * intermediateDist; Node tmp = NavigationGraph.CreateNode(pos, cluster); if (tmp == null) { // If we fail creating an intermediate node, try to use the closest one Node close = NavigationGraph.GetClosestNode(pos); if (close != null && (close.position - pos).magnitude < NavigationGraph.wallOffset) { tmp = close; } else { // if we can't have a close node, just keep a long link and don't bother more prev.AddLink(node); break; } } addedNewNodes = true; // No need to raycast to check the link : we already did one before on a longest distance // (we already know that the fartest nodes can see each other) tmp.AddLink(prev); prev = tmp; nb--; } prev.AddLink(node); // don't forget to link the last node } else if (dist < NavigationGraph.nodesMaxDistance) { AddLink(node, dist); } } } return(addedNewNodes); }
// Start is called before the first frame update void Start() { //example we want 1 block to be 4x4 and there to be 2x2 number of blocks //n = 4 //b = 2 //(n-1)*b+1 //we would need 7 by 7 tiles to generate this level var temp = (size - 1) * blocks + 1; //Generate outer walls for (int edge1 = -1; edge1 <= temp; edge1++) { Instantiate(outerTile, new Vector3(edge1 * _tileWidth, 0, -1 * _tileWidth), Quaternion.Euler(0, 90 * Random.Range(0, 4), 0)); Instantiate(outerTile, new Vector3(edge1 * _tileWidth, 0, temp * _tileWidth), Quaternion.Euler(0, 90 * Random.Range(0, 4), 0)); } for (int edge2 = 0; edge2 < temp; edge2++) { Instantiate(outerTile, new Vector3(-1 * _tileWidth, 0, edge2 * _tileWidth), Quaternion.Euler(0, 90 * Random.Range(0, 4), 0)); Instantiate(outerTile, new Vector3(temp * _tileWidth, 0, edge2 * _tileWidth), Quaternion.Euler(0, 90 * Random.Range(0, 4), 0)); } //Generate play area for (int i = 0; i < temp; i++) { for (int j = 0; j < temp; j++) { GameObject obj; Transform npc_spawn = null; if (i % (size - 1) == 0 && j % (size - 1) == 0) { obj = _crossRoadScript.Generate(i, j); npc_spawn = obj.transform.Find("NPC Spawn point"); } else if (i % (size - 1) == 0 || j % (size - 1) == 0) { obj = _roadScript.Generate(i, j); npc_spawn = obj.transform.Find("NPC Spawn point"); } else if ((i % (size - 1) == 1 || j % (size - 1) == 1 || i % (size - 1) == size - 2 || j % (size - 1) == size - 2) && Random.value > (1 - tavernPercent)) { obj = _tavernScript.Generate(i, j); // Don't generate NPC on taverns yet, we will do it after the player drinks a beer } else { obj = _fillerScript.Generate(i, j); npc_spawn = obj.transform.Find("NPC Spawn point"); } // Small hack to refresh the colliders (saw that on internet, no idea if it really working or not) obj.SetActive(false); obj.SetActive(true); //NavigationGraph.AddNodes(obj); foreach (Transform child in obj.transform) { if (child.CompareTag("GraphNode")) { NavigationGraph.CreateNode(child.position); Destroy(child.gameObject); } } // Spawn a NPC with 20% chance, could be adjusted if we have a difficulty setting // (the issue stated to spawn a fixed amount of NPC, but i think a fixed probability would do the trick too) if (Random.Range(0, 4) == 3 && npc_spawn != null) { SpawnNPC(npc_spawn.position); } } } NavigationGraph.ReGenerateAllLinks(); }