/// <summary> /// Generates the environment for the experiments. /// </summary> private void GenerateEnvironment() { // delete old obstacles if (obstaclesList.Count > 0) { foreach (GameObject obj in obstaclesList) { obj.SetActive(false); Destroy(obj.gameObject); } obstaclesList.Clear(); } // set new track width grid.gridWorldSize = new Vector2(Random.Range(12, 20), grid.gridWorldSize.y); Vector2 gS = grid.gridWorldSize; // place detectable obstacles on the sidelines for (int i = 0; i < sideObstacleCount; i++) { // calculate coordinates float x = RandomFromDistribution.RandomRangeNormalDistribution(-3f, 4f, RandomFromDistribution.ConfidenceLevel_e._99) + gS.x / 2; float z = Mathf.Lerp(-gS.y / 2, gS.y / 2, (float)i / (float)sideObstacleCount); // objects on the right GameObject obsToBuild = loadedObstacles[Random.Range(0, loadedObstacles.Length)]; Vector3 obsSize = obsToBuild.GetComponentInChildren <Renderer>().bounds.size; float maxSize = Mathf.Max(obsSize.x, obsSize.y); Vector3 newPos = new Vector3(x + maxSize / 3, 0f, z); Quaternion newRot = Quaternion.Euler(Random.Range(-5f, 5f), Random.Range(0f, 360f), Random.Range(-5f, 5f)); GameObject newObs = Instantiate(obsToBuild, newPos, newRot) as GameObject; newObs.GetComponentInChildren <MeshRenderer>().material = ObstacleMat; newObs.layer = 8; obstaclesList.Add(newObs); // objects on the left obsToBuild = loadedObstacles[Random.Range(0, loadedObstacles.Length)]; obsSize = obsToBuild.GetComponentInChildren <Renderer>().bounds.size; maxSize = Mathf.Max(obsSize.x, obsSize.y); newPos = new Vector3(-x - maxSize / 3, 0f, z); newRot = Quaternion.Euler(Random.Range(-5f, 5f), Random.Range(0f, 360f), Random.Range(-5f, 5f)); newObs = Instantiate(obsToBuild, newPos, newRot) as GameObject; newObs.GetComponentInChildren <MeshRenderer>().material = ObstacleMat; newObs.layer = 8; obstaclesList.Add(newObs); } // update current obstacle ID if not set to fixed if (!fixedObstacle) { if (currentObstacleID < loadedObstacles.Length - 1) { currentObstacleID++; } else { Debug.Log("Epoch: " + currentEpoch++); currentObstacleID = 0; } } // load central obstacle to avoid GameObject otb = loadedObstacles[currentObstacleID]; Vector3 oS = otb.GetComponentInChildren <Renderer>().bounds.size; // make sure it's not too big float mS = Mathf.Max(oS.x, oS.y); while (mS > grid.gridWorldSize.x / 2f) { otb = loadedObstacles[Random.Range(0, loadedObstacles.Length)]; oS = otb.GetComponentInChildren <Renderer>().bounds.size; mS = Mathf.Max(oS.x, oS.y); } // place it Vector3 nP = new Vector3(Random.value - 0.5f, Random.value - 0.25f, 0f); Quaternion nR = Quaternion.Euler(Random.Range(-5f, 5f), Random.Range(0f, 360f), Random.Range(-5f, 5f)); currentObstacle = Instantiate(otb, nP, nR) as GameObject; obstaclesList.Add(currentObstacle); // make obstacle undetectable in x % of the cases to force crashes if (Random.value < crashChance) { currentObstacle.layer = 9; currentObstacle.GetComponentInChildren <MeshRenderer>().material = CrashObjMat; isSteeringData = false; } else { currentObstacle.layer = 8; currentObstacle.GetComponentInChildren <MeshRenderer>().material = ObstacleMat; isSteeringData = true; } grid.Awake(); }