コード例 #1
0
    //find all auxins near him (Voronoi Diagram)
    //call this method from game controller, to make it sequential for each agent
    public void FindNearAuxins()
    {
        //clear them all, for obvious reasons
        myAuxins.Clear();

        //get all auxins on my cell
        List <AuxinControllerBase> cellAuxins = cell.GetComponent <CellControllerBase>().GetAuxins();

        //iterate all cell auxins to check distance between auxins and agent
        for (int i = 0; i < cellAuxins.Count; i++)
        {
            //see if the distance between this agent and this auxin is smaller than the actual value, and inside agent radius
            float distance = Vector3.Distance(transform.position, cellAuxins[i].position);
            if (distance < cellAuxins[i].GetMinDistance() && distance <= agentRadius)
            {
                //take the auxin!!
                //if this auxin already was taken, need to remove it from the agent who had it
                if (cellAuxins[i].taken == true)
                {
                    GameObject otherAgent = cellAuxins[i].GetAgent();
                    otherAgent.GetComponent <AgentControllerBase>().myAuxins.Remove(cellAuxins[i]);
                }
                //auxin is taken
                cellAuxins[i].taken = true;
                //change the color (visual purpose)
                //cellAuxins[i].material.color = color;
                //auxin has agent
                cellAuxins[i].SetAgent(this.gameObject);
                //update min distance
                cellAuxins[i].SetMinDistance(distance);
                //update my auxins
                myAuxins.Add(cellAuxins[i]);
            }
        }

        //find all neighbours cells
        //default
        Terrain terrain = GameObject.Find("Terrain").GetComponent <Terrain>();
        int     startX  = (int)cell.transform.position.x - 2;
        int     startZ  = (int)cell.transform.position.z - 2;
        int     endX    = (int)cell.transform.position.x + 2;
        int     endZ    = (int)cell.transform.position.z + 2;
        //distance from agent to cell, to define agent new cell
        float distanceToCell = Vector3.Distance(transform.position, cell.transform.position);

        //see if it is in some border
        if ((int)cell.transform.position.x == 1)
        {
            startX = (int)cell.transform.position.x;
        }
        if ((int)cell.transform.position.z == 1)
        {
            startZ = (int)cell.transform.position.z;
        }
        if ((int)cell.transform.position.x == (int)terrain.terrainData.size.x - 1)
        {
            endX = (int)cell.transform.position.x;
        }
        if ((int)cell.transform.position.z == (int)terrain.terrainData.size.z - 1)
        {
            endZ = (int)cell.transform.position.z;
        }

        //iterate to find the cells
        //2 in 2, since the radius of each cell is 1 = diameter 2
        for (int i = startX; i <= endX; i = i + 2)
        {
            for (int j = startZ; j <= endZ; j = j + 2)
            {
                int nameX = i - 1;
                int nameZ = j - 1;
                //find the cell
                GameObject neighbourCell = CellControllerBase.GetCellByName("cell" + nameX + "-" + nameZ);

                //get all auxins on neighbourcell
                cellAuxins = neighbourCell.GetComponent <CellControllerBase>().GetAuxins();

                //iterate all cell auxins to check distance between auxins and agent
                for (int c = 0; c < cellAuxins.Count; c++)
                {
                    //see if the distance between this agent and this auxin is smaller than the actual value, and smaller than agent radius
                    float distance = Vector3.Distance(transform.position, cellAuxins[c].position);
                    if (distance < cellAuxins[c].GetMinDistance() && distance <= agentRadius)
                    {
                        //take the auxin!!
                        //if this auxin already was taken, need to remove it from the agent who had it
                        if (cellAuxins[c].taken == true)
                        {
                            GameObject otherAgent = cellAuxins[c].GetAgent();
                            otherAgent.GetComponent <AgentControllerBase>().myAuxins.Remove(cellAuxins[c]);
                        }
                        //auxin is taken
                        cellAuxins[c].taken = true;
                        //change the color (visual purpose)
                        //cellAuxins[i].material.color = color;
                        //auxin has agent
                        cellAuxins[c].SetAgent(this.gameObject);
                        //update min distance
                        cellAuxins[c].SetMinDistance(distance);
                        //update my auxins
                        myAuxins.Add(cellAuxins[c]);
                    }
                }

                //see distance to this cell
                float distanceToNeighbourCell = Vector3.Distance(transform.position, neighbourCell.transform.position);
                if (distanceToNeighbourCell < distanceToCell)
                {
                    distanceToCell = distanceToNeighbourCell;
                    SetCell(neighbourCell);
                }
            }
        }
    }
コード例 #2
0
    // Use this for initialization
    void Awake()
    {
        //camera height and center position
        //scene is 3:2 scale, so we divide for 3 or 2, depending the parameter
        //float cameraHeight = scenarioSizeX/3;
        //float cameraPositionX = scenarioSizeX/2;
        //float cameraPositionZ = scenarioSizeZ/2;
        //GameObject camera = GameObject.Find ("Camera");
        //camera.transform.position = new Vector3(cameraPositionX, camera.transform.position.y, cameraPositionZ);
        //camera.GetComponent<Camera>().orthographicSize = cameraHeight;

        Terrain terrain = GameObject.Find("Terrain").GetComponent <Terrain>();

        //change terrain size according informed
        terrain.terrainData.size = new Vector3(scenarioSizeX, terrain.terrainData.size.y, scenarioSizeZ);

        //Get map size
        spawnPositionX = (int)Mathf.Floor(terrain.terrainData.size.x - 1f);
        spawnPositionZ = (int)Mathf.Floor(terrain.terrainData.size.z - (terrain.terrainData.size.z - 2f));

        //if loadConfigFile is checked, we do not generate the initial scenario. We load it from the Config.xml (or something like this) file
        if (loadConfigFile)
        {
            LoadConfigFile();

            //build the navmesh at runtime
            UnityEditor.AI.NavMeshBuilder.BuildNavMesh();
        }
        else
        {
            //build the navmesh at runtime
            UnityEditor.AI.NavMeshBuilder.BuildNavMesh();

            //draw Obstacles
            //DrawObstacles();

            //first of all, create all cells (with this scene and this agentRadius = 1 : 150 cells)
            //since radius = 1; diameter = 2. So, iterate 2 in 2
            //if the radius varies, this 2 operations adjust the cells
            Vector3 newPosition = new Vector3(cell.transform.position.x * agentRadius,
                                              cell.transform.position.y * agentRadius, cell.transform.position.z * agentRadius);
            Vector3 newScale = new Vector3(cell.transform.localScale.x * agentRadius,
                                           cell.transform.localScale.y * agentRadius, cell.transform.localScale.z * agentRadius);

            for (float i = 0; i < terrain.terrainData.size.x; i = i + agentRadius * 2)
            {
                for (float j = 0; j < terrain.terrainData.size.z; j = j + agentRadius * 2)
                {
                    //instantiante a new cell
                    GameObject newCell = Instantiate(cell, new Vector3(newPosition.x + i, newPosition.y, newPosition.z + j), Quaternion.identity) as GameObject;
                    //change his name
                    newCell.GetComponent <CellControllerBase>().cellName = newCell.name = "cell" + i + "-" + j;
                    //change scale
                    newCell.transform.localScale = newScale;
                }
            }

            //just to see how many cells were generated
            GameObject[] allCells = GameObject.FindGameObjectsWithTag("Cell");
            //Debug.Log(allCells.Length);

            //lets set the qntAuxins for each cell according the density estimation
            float densityToQnt = PORC_QTD_Marcacoes;

            densityToQnt *= 2f / (2.0f * auxinRadius);
            densityToQnt *= 2f / (2.0f * auxinRadius);

            qntAuxins = (int)Mathf.Floor(densityToQnt);
            //Debug.Log(qntAuxins);

            //for each cell, we generate his auxins
            for (int c = 0; c < allCells.Length; c++)
            {
                //Dart throwing auxins
                //use this flag to break the loop if it is taking too long (maybe there is no more space)
                int flag = 0;
                for (int i = 0; i < qntAuxins; i++)
                {
                    float x = Random.Range(allCells[c].transform.position.x - 0.99f, allCells[c].transform.position.x + 0.99f);
                    float z = Random.Range(allCells[c].transform.position.z - 0.99f, allCells[c].transform.position.z + 0.99f);

                    //see if there are auxins in this radius. if not, instantiante
                    List <AuxinControllerBase> allAuxinsInCell = allCells[c].GetComponent <CellControllerBase>().GetAuxins();
                    bool canIInstantiante = true;
                    for (int j = 0; j < allAuxinsInCell.Count; j++)
                    {
                        float distanceAA = Vector3.Distance(new Vector3(x, 0f, z), allAuxinsInCell[j].position);

                        //if it is too near, i cant instantiante. found one, so can Break
                        if (distanceAA < auxinRadius)
                        {
                            canIInstantiante = false;
                            break;
                        }
                    }

                    //if i have found no auxin, i still need to check if is there obstacles on the way
                    if (canIInstantiante)
                    {
                        //sphere collider to try to find the obstacles
                        Collider[] hitColliders = Physics.OverlapSphere(new Vector3(x, 0f, z), auxinRadius);
                        {
                            //if found some
                            if (hitColliders.Length > 0)
                            {
                                //for each of them, verify if it is an Obstacle. If it is, i cannot instantiate
                                for (int s = 0; s < hitColliders.Length; s++)
                                {
                                    if (hitColliders[s].gameObject.tag == "Obstacle")
                                    {
                                        canIInstantiante = false;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    //canIInstantiante???
                    if (canIInstantiante)
                    {
                        AuxinControllerBase newAuxin = new AuxinControllerBase();
                        //change his name
                        newAuxin.name = "auxin" + c + "-" + i;
                        //this auxin is from this cell
                        newAuxin.SetCell(allCells[c]);
                        //set position
                        newAuxin.position = new Vector3(x, 0f, z);

                        //add this auxin to this cell
                        allCells[c].GetComponent <CellControllerBase>().AddAuxin(newAuxin);

                        //reset the flag
                        flag = 0;
                    }
                    else
                    {
                        //else, try again
                        flag++;
                        i--;
                    }

                    //if flag is above qntAuxins (*2 to have some more), break;
                    if (flag > qntAuxins * 2)
                    {
                        //reset the flag
                        flag = 0;
                        break;
                    }
                }
            }

            //to avoid a freeze
            int doNotFreeze = 0;
            //instantiate qntAgents Agents
            for (int i = 0; i < qntAgents; i++)
            {
                //if we are not finding space to set the agent, lets update the maxZ position to try again
                if (doNotFreeze > qntAgents)
                {
                    doNotFreeze     = 0;
                    spawnPositionZ += 2;
                }

                //default
                //scenarioType 0
                //sort out a cell
                float x = (int)Random.Range(3f, spawnPositionX);
                float z = (int)Random.Range(3f, spawnPositionZ);
                //need to me uneven, for the cells are too
                while (x % 2 == 0 || z % 2 == 0)
                {
                    x = (int)Random.Range(1f, spawnPositionX);
                    z = (int)Random.Range(1f, spawnPositionZ);
                }
                //Debug.Log (x+"--"+z);
                GameObject[] allGoals  = GameObject.FindGameObjectsWithTag("Goal");
                GameObject   choosen   = new GameObject();
                float        menorDist = float.PositiveInfinity;
                foreach (GameObject g in allGoals)
                {
                    float dist = Vector3.Distance(new Vector3(x, 0, z), g.transform.position);
                    if (dist < menorDist)
                    {
                        menorDist = dist;
                        choosen   = g;
                    }
                }
                GameObject thisGoal = choosen;

                if (scenarioType == 1)
                {
                    //scenarioType 1
                    //half agents, so
                    if (i % 2 != 0)
                    {
                        //z size = 20
                        z = (int)Random.Range(terrain.terrainData.size.z, terrain.terrainData.size.z - spawnPositionZ);
                        //need to me uneven, for the cells are too
                        while (z % 2 == 0)
                        {
                            z = (int)Random.Range(terrain.terrainData.size.z, terrain.terrainData.size.z - spawnPositionZ);
                        }
                        thisGoal = allGoals[1];
                    }
                }

                //find the cell in x - z coords, using his name
                int        nameX     = (int)x - 1;
                int        nameZ     = (int)z - 1;
                GameObject foundCell = CellControllerBase.GetCellByName("cell" + nameX + "-" + nameZ);
                //generate the agent position
                x = Random.Range(foundCell.transform.position.x - 1f, foundCell.transform.position.x + 1f);
                z = Random.Range(foundCell.transform.position.z, foundCell.transform.position.z + 5f);

                //see if there are agents in this radius. if not, instantiante
                Collider[] hitColliders = Physics.OverlapSphere(new Vector3(x, 0, z), 0.5f);
                //here we have all colliders hit, where we can have auxins too. So, lets see which of these are Player
                int pCollider = 0;
                for (int j = 0; j < hitColliders.Length; j++)
                {
                    if (hitColliders[j].gameObject.tag == "Player")
                    {
                        //if we find one, it is enough. Break!
                        pCollider++;
                        break;
                    }
                }

                //if found a player in the radius, do not instantiante. try again
                if (pCollider > 0)
                {
                    //try again
                    i--;
                    doNotFreeze++;
                    continue;
                }
                else
                {
                    GameObject newAgent = Instantiate(agent, new Vector3(x, 0f, z), Quaternion.identity) as GameObject;
                    //change his name
                    newAgent.name = "agent" + i;
                    //random agent color
                    newAgent.GetComponent <AgentControllerBase>().SetColor(new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f)));
                    //agent cell
                    newAgent.GetComponent <AgentControllerBase>().SetCell(foundCell);
                    //agent radius
                    newAgent.GetComponent <AgentControllerBase>().agentRadius = agentRadius;

                    //if lane scene, black and white
                    if (scenarioType == 1)
                    {
                        //scenarioType 1
                        //half agents, so
                        if (i % 2 != 0)
                        {
                            newAgent.GetComponent <AgentControllerBase>().SetColor(new Color(0f, 0f, 0f));
                        }
                        else
                        {
                            newAgent.GetComponent <AgentControllerBase>().SetColor(new Color(1f, 1f, 1f));
                        }
                    }

                    newAgent.GetComponent <MeshRenderer>().material.color = newAgent.GetComponent <AgentControllerBase>().GetColor();

                    //agent goal
                    newAgent.GetComponent <AgentControllerBase>().go = thisGoal;
                }
            }
        }
        Debug.Log("Termino");
    }