示例#1
0
    // 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);
    }
示例#2
0
    // 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();
    }