void SetCurrentNode(TutorialNode node)
 {
     m_currentNode = node;
     if (m_currentNode != null)
     {
         Debug.Log(">>>> Lock Node: " + node.name);
         m_mask.Active = true;
         m_mask.SetPos(node.Pos);
     }
     else
     {
         // All steps finished
         OnAllStepsFinished();
     }
 }
        /// <summary>
        /// Pass the event to the target <T>
        /// 将事件传递给目标物件<T>
        /// </summary>
        /// <param name="data"></param>
        /// <param name="function"></param>
        /// <typeparam name="T"></typeparam>
        private void SearchTarget <T>(PointerEventData data, ExecuteEvents.EventFunction <T> function) where T : IEventSystemHandler
        {
            var results = new List <RaycastResult>();

            EventSystem.current.RaycastAll(data, results);
            var current = data.pointerCurrentRaycast.gameObject;

            for (int i = 0; i < results.Count; i++)
            {
                // Debug.Log("Current: " + current.name);

                if (current != results[i].gameObject)
                {
                    TutorialNode node = results[i].gameObject.GetComponent <TutorialNode>();
                    if (node != null)
                    {
                        this.Active = false;
                        node.OnPassEvent <T>(data, function);
                        break;
                    }
                }
            }
        }
 void OnTutorialStepFinished(TutorialNode node)
 {
     SetCurrentNode(node.nextNode);
 }