// called when player bullet hit on invader. check invader script
        public void DestroyInvader(Invader thisInvader)
        {
            // for boss checking
            if (m_lastInviderColumnIndexCntr < 0)
            {
                m_lastInviderColumnIndex = thisInvader.m_coumnIndex; m_lastInviderColumnIndexCntr = 1;
            }
            else
            {
                int cntr = m_lastInviderColumnIndex == thisInvader.m_coumnIndex ? m_lastInviderColumnIndexCntr + 1 : 1; // adding to the colmns index
                m_lastInviderColumnIndexCntr = cntr;
                m_lastInviderColumnIndex     = thisInvader.m_coumnIndex;
            }

            bool timetoBoSS = m_lastInviderColumnIndexCntr >= m_maxInvaderColumnCntr ? true : false;

            if (timetoBoSS && m_lastScoreBossShown + m_minScoreNeeded < m_gameScoreSO.Value)
            {
                if (m_bossInvader == null)
                {
                    m_lastScoreBossShown = m_gameScoreSO.Value;
                    CreatNewBoss();
                    Debug.Log("creating new boss : USER Generated");
                    m_lastBossShownTime = Time.time;
                }
            }

            m_totalAliveInviders--; // decrement the invader count
            m_totalAliveInvadersSO.Value = m_totalAliveInviders;
            m_gameScoreSO.Value          = m_gameScoreSO.Value + thisInvader.m_killValue.Value;
            Vector3 invaderLastPos = thisInvader.transform.position;

            m_invaderRows[thisInvader.m_rowIndex][thisInvader.m_coumnIndex] = null;
            SpaceInvaderAbstractFactory spaceInvaderFactory = SpaceInvaderFactoryProducer.GetFactory("InvaderFactory"); // accessomg InvaderFactory

            spaceInvaderFactory.RecycleInvader(thisInvader);

            spaceInvaderFactory = SpaceInvaderFactoryProducer.GetFactory("EffectsFactory");
            Effects invadeExplodeEffect = spaceInvaderFactory.GetEffects(EffectsType.AlianExplodeEffect);

            invadeExplodeEffect.transform.position = invaderLastPos;
            invadeExplodeEffect.gameObject.SetActive(true);
            invadeExplodeEffect.DestroyAfterSomeTime(.15f);
            m_audioSource.PlayOneShot(m_invaderExlodeClip);

            UpdateTimeIntervalOFMove();    // check against the number of inviders left and increas the move speed

            if (m_totalAliveInviders == 0) //  next wave
            {
                m_invaderGridState = InvaderGridState.Pause;
                return;
                // for now there wont be any new waves, game will be over at this point
                // wil add new wave feature in the next update
            }
        }
        // creates the Invaders in a grid manner
        // with the help of Grid class, this creates a new invader grids and stores in an jagged array
        private void CreateInvaderGrid()
        {
            if (m_invaderTypeRow.Length < 1)
            {
                return;
            }

            m_gridRows    = m_invaderTypeRow.Length;                       // number of rows of invaders
            m_gridColumns = m_invaderRowLength;                            // row counts is basically max Coulumn

            m_leftMaxMoveCheckIndex  = new RawCoumn(0, 0);                 // first row firt column
            m_rightMaxMoveCheckIndex = new RawCoumn(0, m_gridColumns - 1); // first row last column

            m_invaderRows = new Invader[m_gridRows][];
            for (int i = 0; i < m_gridRows; i++)
            {
                m_invaderRows[i] = new Invader[m_gridColumns];
            }

            m_2DGrid = new Grid2D(m_gridRows, m_gridColumns, m_gridCellWidth, m_gridCellHeight, m_gridRootObject.position);
            SpaceInvaderAbstractFactory spaceInvaderFactory = SpaceInvaderFactoryProducer.GetFactory("InvaderFactory"); // accessomg InvaderFactory

            for (int i = 0; i < m_gridRows; i++)
            {
                InvaderTypes rowType = m_invaderTypeRow[i]; // current row type
                for (int j = 0; j < m_gridColumns; j++)
                {
                    Cell cell = m_2DGrid.Cells[i][j];

                    Invader invader = spaceInvaderFactory.GetInvader(rowType); // asking for type of invaders from the factory
                    invader.gameObject.transform.position = cell.m_center;

                    invader.m_invaderManger = this;
                    invader.m_rowIndex      = i;
                    invader.m_coumnIndex    = j;
                    m_totalAliveInviders++;
                    m_totalAliveInvadersSO.Value = m_totalAliveInviders;
                    m_invaderRows[i][j]          = invader; // assigning to the invader array
                }
            }

            m_firableColumn    = m_invaderRows[m_invaderRows.Length - 1];
            m_invaderGridState = InvaderGridState.Created;
            // Invaders will be in hidden state at this point and next ShowAllInviders will display invaders with animation
        }
        // Showing invaders with animation
        private IEnumerator ShowAllInviders(Action onComplete)
        {
            for (int i = m_invaderRows.Length - 1; i >= 0; i--) // start looping from bottom left
            {
                Invader[] invaderRow = m_invaderRows[i];        // current row
                for (int j = 0; j < m_gridColumns; j++)
                {
                    Invader invader = invaderRow[j];
                    invader.gameObject.SetActive(true);     // start vible to camera

                    yield return(new WaitForSeconds(.04f)); // slight delay for the animations
                }
            }
            m_invaderGridState = InvaderGridState.Displayed;
            yield return(new WaitForSeconds(.2f));

            m_invaderHorMovDirection = 1; // setting moving directio as right
            m_invaderGridState       = InvaderGridState.Moving;
            m_lastBossShownTime      = Time.time;

            yield return(null);

            onComplete?.Invoke();
        }
 // initializes inivader manger
 private void Initialize()
 {
     m_totalAliveInviders = 0;
     m_invaderGridState   = InvaderGridState.NotReady;
     m_moveUpdateInterval = .5f;
 }
 public void SetStateToPause()
 {
     m_invaderGridState = InvaderGridState.Pause;
 }