/// <summary>
        /// Check and remove out-of-view segment
        /// </summary>
        public void CheckOutOfViewSegment()
        {
            if (m_CurrentSegments.Count == 0)
            {
                return;
            }

            //Just have to check the first segment
            TrackSegment segmentToCheck = m_CurrentSegments[0];

            //Return to pool when out of view
            if (mainCamera.transform.position.x - mainCamera.GetHalfCameraWidth() - segmentToCheck.endPoint.position.x > m_ScreenOffsetError)
            {
                segmentToCheck.RemoveSelf();
                m_CurrentSegments.Remove(segmentToCheck);
            }
        }
        protected void SpawnNewSegment()
        {
            if (trackSegments.Length == 0)
            {
                return;
            }

            //Init random seed
            if (m_TrackSeed != -1)
            {
                Random.InitState(m_TrackSeed);
            }
            else
            {
                Random.InitState((int)System.DateTime.Now.Ticks);
            }


            //Spawn segment
            TrackSegment segmentToUse;
            bool         spawnObstacles = true;

            //Use safe segment
            if (m_CurrentSafeSegmentCount < m_MaxSafeSegmentCount)
            {
                segmentToUse = trackSegments[0];
                m_CurrentSafeSegmentCount++;
                spawnObstacles = false;
            }
            else
            {
                //Random track to spawn
                int randomIndex = Random.Range(0, trackSegments.Length);
                segmentToUse = trackSegments[randomIndex];
            }

            //Calculate spawn position
            Vector3 spawnPosition;

            if (m_CurrentSegment == null)
            {
                spawnPosition = transform.position;
            }
            else
            {
                spawnPosition = m_CurrentSegment.endPoint.position + (segmentToUse.transform.position - segmentToUse.startPoint.position);
            }

            //Spawn segment from object pool
            DefaultObjectPool poolToUse  = DefaultObjectPool.GetObjectPool(segmentToUse.gameObject, 1);
            DefaultPoolObject poolObject = poolToUse.Pop(spawnPosition);

            m_CurrentSegment            = poolObject.transform.GetComponent <TrackSegment>();
            m_CurrentSegment.poolObject = poolObject;
            //Spawn obstacles
            if (spawnObstacles)
            {
                m_CurrentSegment.SpawnObstacles();
            }

            //Add to list
            m_CurrentSegments.Add(m_CurrentSegment);
        }