Beispiel #1
0
    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);
            }
        }
    }