/// <summary>
        /// Creates perception vector to be used as part of an observation of an agent.
        /// </summary>
        /// <returns>The partial vector observation corresponding to the set of rays</returns>
        /// <param name="rayDistance">Radius of rays</param>
        /// <param name="rayAngles">Anlges of rays (starting from (1,0) on unit circle).</param>
        /// <param name="detectableObjects">List of tags which correspond to object types agent can see</param>
        /// <param name="startOffset">Starting heigh offset of ray from center of agent.</param>
        /// <param name="endOffset">Ending height offset of ray from center of agent.</param>
        public List <float> Perceive(float rayDistance,
                                     float[] rayAngles, string[] detectableObjects,
                                     float startOffset, float endOffset)
        {
            perceptionBuffer.Clear();
            objects.Clear();
            // For each ray sublist stores categorial information on detected object
            // along with object distance.
            foreach (float angle in rayAngles)
            {
                endPosition = transform.TransformDirection(
                    PolarToCartesian(rayDistance, angle));
                endPosition.y = endOffset;
                if (Application.isEditor)
                {
                    Debug.DrawRay(transform.position + new Vector3(0f, startOffset, 0f) - transform.forward * Consts.GroundScale,
                                  endPosition, Color.black, 0.01f, true);
                }
                //extra 3 for 1,if not found object 2, enemy isalive, the distance to the object
                float[] subList = new float[detectableObjects.Length + 3];
                if (Physics.SphereCast(transform.position +
                                       new Vector3(0f, startOffset, 0f) - transform.forward * Consts.GroundScale, Consts.GroundScale,
                                       endPosition, out hit, rayDistance))
                {
                    for (int i = 0; i < detectableObjects.Length; i++)
                    {
                        if (hit.collider.gameObject.CompareTag(detectableObjects[i]))
                        {
                            //objects.Add(hit.collider.gameObject);
                            if (hit.collider.gameObject.CompareTag("Enemy"))
                            {
                                if (player != null)
                                {
                                    rewardFlag = false;
                                    player.AddReward(0.001f);
                                }

                                //Debug.Log("detect enemy at pos" + hit.point);
                            }
                            if (hit.collider.gameObject.CompareTag("target"))
                            {
                                if (enemy != null)
                                {
                                    enemy.AddReward(0.001f);
                                }
                            }

                            subList[i] = 1;

                            subList[detectableObjects.Length + 1] = hit.point.x - transform.position.x;
                            subList[detectableObjects.Length + 2] = hit.point.z - transform.position.z;

                            break;
                        }
                    }
                }
                else
                {
                    subList[detectableObjects.Length] = 1f;
                }
                string test = "";
                foreach (var item in subList)
                {
                    test += item.ToString();
                    test += ",";
                }
                //Debug.Log(test);
                perceptionBuffer.AddRange(subList);
            }

            return(perceptionBuffer);
        }