protected override void Awake()
 {
     for (int holeIndex = 0; holeIndex < m_Holes.Count; ++holeIndex)
     {
         tnCarambolaHole hole = m_Holes[holeIndex];
         if (hole != null)
         {
             hole.SetManager(this);
         }
     }
 }
    void OnDisable()
    {
        Messenger.RemoveListener("FieldReset", OnFieldReset);
        Messenger.RemoveListener("KickOff", OnKickOff);

        for (int holeIndex = 0; holeIndex < m_Holes.Count; ++holeIndex)
        {
            tnCarambolaHole hole = m_Holes[holeIndex];
            if (hole != null)
            {
                hole.onPreHoleOccuredEvent  -= OnPreHoleOccuredEvent;
                hole.onPostHoleOccuredEvent -= OnPostHoleOccuredEvent;
            }
        }
    }
    private void OnFieldReset()
    {
        for (int holeIndex = 0; holeIndex < m_Holes.Count; ++holeIndex)
        {
            tnCarambolaHole hole = m_Holes[holeIndex];

            if (hole == null)
            {
                continue;
            }

            hole.enabled = false; // Hole clear itself in OnDisable;
        }

        m_Cache.Clear();
    }
    private void OnKickOff()
    {
        for (int holeIndex = 0; holeIndex < m_Holes.Count; ++holeIndex)
        {
            tnCarambolaHole hole = m_Holes[holeIndex];

            if (hole == null)
            {
                continue;
            }

            hole.enabled = true; // Hole clear itself in OnEnable;
        }

        m_Cache.Clear();
    }
    // MonoBehaviour's interface

    void OnDrawGizmos()
    {
        if (!m_DrawGizmos)
        {
            return;
        }

        Gizmos.color = Color.blue;

        for (int holesIndex = 0; holesIndex < m_Holes.Count; ++holesIndex)
        {
            tnCarambolaHole hole = m_Holes[holesIndex];
            if (hole != null)
            {
                Gizmos.DrawSphere(hole.transform.position, hole.threshold);
            }
        }
    }
    // INTERNALS

    private void CheckCollisions()
    {
        for (int index = 0; index < m_Cache.count; ++index)
        {
            bool toRemove = true;

            if (!m_Cache.IsAlreadyTeleported(index))
            {
                continue;
            }

            Collider2D collider = m_Cache.GetCollider(index);

            if (collider != null)
            {
                for (int holeIndex = 0; holeIndex < m_Holes.Count; ++holeIndex)
                {
                    tnCarambolaHole hole = m_Holes[holeIndex];

                    if (hole == null)
                    {
                        continue;
                    }

                    if (hole.IsCollidingWith(collider))
                    {
                        toRemove = false;
                        break;
                    }
                }
            }

            if (toRemove)
            {
                m_Cache.RemoveAt(index);
                index = -1;
            }
        }
    }