public override void CollectObservations() { GameObject onCollisionCourse; List <GameObject> currentHazards; List <GameObject> observedHazards = new List <GameObject>(); //First we need to factor in our position relative to the boundaries (normalize to between -1 and 1) AddVectorObs(CalcRelPos(this.transform.position.x, boundary.xMin, boundary.xMax)); AddVectorObs(CalcRelPos(this.transform.position.z, boundary.zMin, boundary.zMax)); //The game controller has been modified to keep a list of current hazards - but needs to clear destroyed ones gController.TidyUpHazardList(); currentHazards = gController.CurrentHazards; //The number of objects and their relative position we observe dictates the number of vectors (which is limited) //The observed hazards should be those closest to the agent. observedHazards = SelectClosest(currentHazards, numHazardsObserved); observedHazards.ForEach(AddHazardVectors); //Fill up unused observation vectors. Using 1 instead of 0, to reflect the hazard being far away (instead of close) for (int i = 0; i < numHazardsObserved - observedHazards.Count; i++) { AddVectorObs(1); AddVectorObs(1); } //since the AI can only see a certain number of hazards it's fair to give a collision warning & distance if (rBody == null) { AddVectorObs(0); } else { // First sort hazards by their z position (descending because smaller means closer) currentHazards.Sort((a, b) => { if (a.transform.position.z > b.transform.position.z) { return(1); } else { return(-1); } }); //Find the object which is in front of the ship and on a similar x coordinate onCollisionCourse = currentHazards.Find(h => h.transform.position.z > rBody.transform.position.z && h.transform.position.x > rBody.transform.position.x - 0.5f && h.transform.position.x < rBody.transform.position.x + 0.5f); //Add it's distance as an observation vector if (onCollisionCourse == null) { AddVectorObs(-1); } else { AddVectorObs(Vector3.Distance(rBody.transform.position, onCollisionCourse.transform.position) / (Math.Abs(boundary.zMin) + boundary.zMax)); //Here's a litte danger zone bonus, to make the AI less defencive and boring AddReward(0.01f); } } }