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