//load a csv config file protected void LoadConfigFile() { string line; // Create a new StreamReader, tell it which file to read and what encoding the file StreamReader theReader = new StreamReader(Application.dataPath + "/" + obstaclesFilename, System.Text.Encoding.Default); using (theReader) { int lineCount = 1; int qntObstacles = 0; int qntVertices = 0; int qntTriangles = 0; int controlVertice = 0; int controlTriangle = 0; Vector3[] vertices = new Vector3[qntVertices]; int[] triangles = new int[qntTriangles]; do { line = theReader.ReadLine(); if (line != null && line != "") { //in the first line, we have the qntObstacles to instantiante if (lineCount == 1) { string[] entries = line.Split(':'); qntObstacles = System.Int32.Parse(entries[1]); } //else, if the line has "Obstacle", it is the name. Here starts a new obstacle, so we activate activeObstacle else if (line == "Obstacle") { vertices = null; triangles = null; controlVertice = 0; controlTriangle = 0; } //else, if has qntVertices, starts to list the vertices else if (line.Contains("qntVertices")) { string[] entries = line.Split(':'); qntVertices = System.Int32.Parse(entries[1]); vertices = new Vector3[qntVertices]; } //else, if has qntTraingles, starts to list the triangles else if (line.Contains("qntTriangles")) { string[] entries = line.Split(':'); qntTriangles = System.Int32.Parse(entries[1]); triangles = new int[qntTriangles]; } else { //else, we check if the value has ;. If so, it is a vector3. Otherwise, it is the triangle values string[] entries = line.Split(';'); if (entries.Length > 1) { vertices[controlVertice] = new Vector3(System.Convert.ToSingle(entries[0]), System.Convert.ToSingle(entries[1]), System.Convert.ToSingle(entries[2])); controlVertice++; } else { triangles[controlTriangle] = System.Int32.Parse(entries[0]); controlTriangle++; //if it is the last one, we create the Object if (controlTriangle >= qntTriangles) { GameObject go = new GameObject(); go.AddComponent <MeshFilter>(); go.AddComponent <MeshRenderer>(); MeshFilter mf = go.GetComponent <MeshFilter>(); var mesh = new Mesh(); mf.mesh = mesh; mesh.vertices = vertices; mesh.triangles = triangles; go.AddComponent <BoxCollider>(); go.GetComponent <BoxCollider>().isTrigger = true; go.tag = "Obstacle"; go.name = "Obstacle"; //nav mesh obstacle go.AddComponent <UnityEngine.AI.NavMeshObstacle>(); go.GetComponent <UnityEngine.AI.NavMeshObstacle>().carving = true; go.GetComponent <UnityEngine.AI.NavMeshObstacle>().carveOnlyStationary = false; go.GetComponent <UnityEngine.AI.NavMeshObstacle>().size = new Vector3(go.GetComponent <UnityEngine.AI.NavMeshObstacle>().size.x, 1f, go.GetComponent <UnityEngine.AI.NavMeshObstacle>().size.z); } } } } lineCount++; } while (line != null); } // Done reading, close the reader and return true to broadcast success theReader.Close(); int qntCells = 0; // Create a new StreamReader, tell it which file to read and what encoding the file theReader = new StreamReader(Application.dataPath + "/" + configFilename, System.Text.Encoding.Default); Terrain terrain = GameObject.Find("Terrain").GetComponent <Terrain> (); GameObject camera = GameObject.Find("Camera"); using (theReader) { int lineCount = 1; // While there's lines left in the text file, do this: do { line = theReader.ReadLine(); if (line != null) { //in first line, we have the terrain size if (lineCount == 1) { string[] entries = line.Split(':'); entries = entries[1].Split(','); scenarioSizeX = System.Convert.ToSingle(entries[0]); scenarioSizeZ = System.Convert.ToSingle(entries[1]); terrain.terrainData.size = new Vector3(scenarioSizeX, terrain.terrainData.size.y, scenarioSizeZ); } //in second line, we have the camera position else if (lineCount == 2) { string[] entries = line.Split(':'); entries = entries[1].Split(','); camera.transform.position = new Vector3(System.Convert.ToSingle(entries[0]), System.Convert.ToSingle(entries[1]), System.Convert.ToSingle(entries[2])); camera.GetComponent <Camera>().orthographicSize = System.Convert.ToSingle(entries[3]); } //in the third line, we have the qntCells to instantiante else if (lineCount == 3) { string[] entries = line.Split(':'); qntCells = System.Int32.Parse(entries[1]); } //else, if we are in the qntCells+4 line, we have the qntAuxins to instantiante else if (lineCount == qntCells + 4) { string[] entries = line.Split(':'); qntAuxins = System.Int32.Parse(entries[1]); } //else, if we are in the qntCells+qntAuxins+5 line, it is the qntAgents to instantiate else if (lineCount == qntCells + qntAuxins + 5) { string[] entries = line.Split(':'); qntAgents = System.Int32.Parse(entries[1]); } else { //while we are til qntCells+3 line, we have cells. After that, we have auxins and then, agents if (lineCount <= qntCells + 3) { string[] entries = line.Split(';'); if (entries.Length > 0) { GameObject newCell = Instantiate(cell, new Vector3(System.Convert.ToSingle(entries[1]), System.Convert.ToSingle(entries[2]), System.Convert.ToSingle(entries[3])), Quaternion.identity) as GameObject; //change his name newCell.name = entries[0]; } } else if (lineCount <= qntCells + qntAuxins + 4) { string[] entries = line.Split(';'); if (entries.Length > 0) { //find his cell GameObject hisCell = GameObject.Find(entries[5]); AuxinControllerBase newAuxin = new AuxinControllerBase(); //change his name newAuxin.name = entries[0]; //this auxin is from this cell newAuxin.SetCell(hisCell); //set position newAuxin.position = new Vector3(System.Convert.ToSingle(entries[1]), System.Convert.ToSingle(entries[2]), System.Convert.ToSingle(entries[3])); //alter auxinRadius auxinRadius = System.Convert.ToSingle(entries[4]); //add this auxin to this cell hisCell.GetComponent <CellControllerBase>().AddAuxin(newAuxin); } } else { string[] entries = line.Split(';'); if (entries.Length > 0) { if (lineCount <= qntAuxins + 5 + qntAgents + qntCells) { GameObject newAgent = Instantiate(agent, new Vector3(System.Convert.ToSingle(entries[4]), System.Convert.ToSingle(entries[5]), System.Convert.ToSingle(entries[6])), Quaternion.identity) as GameObject; //change his name newAgent.name = entries[0]; //change his radius newAgent.GetComponent <AgentControllerBase>().agentRadius = System.Convert.ToSingle(entries[1]); //change his maxSpeed newAgent.GetComponent <AgentControllerBase>().maxSpeed = System.Convert.ToSingle(entries[2]); //change his color //new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f)) string[] temp = entries[3].Split('('); temp = temp[1].Split(')'); temp = temp[0].Split(','); newAgent.GetComponent <AgentControllerBase>().SetColor( new Color(System.Convert.ToSingle(temp[0]), System.Convert.ToSingle(temp[1]), System.Convert.ToSingle(temp[2]))); newAgent.GetComponent <MeshRenderer>().material.color = newAgent.GetComponent <AgentControllerBase>().GetColor(); //goal newAgent.GetComponent <AgentControllerBase>().go = GameObject.Find(entries[7]); //cell GameObject theCell = GameObject.Find(entries[8]); newAgent.GetComponent <AgentControllerBase>().SetCell(theCell); //agent radius newAgent.GetComponent <AgentControllerBase>().agentRadius = agentRadius; } } } } } lineCount++; }while (line != null); // Done reading, close the reader and return true to broadcast success theReader.Close(); } //just to see how many auxins were generated GameObject[] qnt = GameObject.FindGameObjectsWithTag("Auxin"); Debug.Log(qnt.Length); }
// 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"); }