//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); } } } }
// 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"); }