Unity 3D\2D手机游戏开发:从学习到产品(第3版)
上QQ阅读APP看书,第一时间看更新

4.5 创建游戏管理器

在前一节,我们创建了UI,但是没有功能,接下来我们将创建一个游戏管理器,它主要用来管理UI,处理鼠标输入和逻辑事件等。

创建脚本GameManager.cs,这里将其添加到Canvas物体上,代码如下所示:

        using UnityEngine;
        using UnityEngine.SceneManagement;
        using System.Collections;
        using System.Collections.Generic;
        using UnityEngine.UI;               //UI控件命名空间的引用
        using UnityEngine.Events;           //UI事件命名空间的引用
        using UnityEngine.EventSystems;     //UI事件命名空间的引用

        public class GameManager : MonoBehaviour {

        public static GameManager Instance;        // 实例
            public LayerMask m_groundlayer;       // 地面的碰撞Layer
            public int m_wave=1;                  // 波数
            public int m_waveMax=10;              // 最大波数
            public int m_life=10;                 // 生命
            public int m_point=30;                // 铜钱数量

            // UI文字控件
            Text m_txt_wave;
            Text m_txt_life;
            Text m_txt_point;
        // UI重新游戏按钮控件
        Button m_but_try;

        // 当前是否选中的创建防守单位的按钮
        bool m_isSelectedButton =false;

        void Awake(){
            Instance = this;
        }
    void Start () {
            // 创建UnityAction,在OnButCreateDefenderDown函数中响应按钮按下事件
            UnityAction<BaseEventData> downAction =
                  new UnityAction<BaseEventData>(OnButCreateDefenderDown);
            // 创建UnityAction,在OnButCreateDefenderDown函数中响应按钮抬起事件
            UnityAction<BaseEventData> upAction =
                  new UnityAction<BaseEventData>(OnButCreateDefenderUp);
            //按钮按下事件
            EventTrigger.Entry down = new EventTrigger.Entry();
            down.eventID = EventTriggerType.PointerDown;
            down.callback.AddListener(downAction);

            //按钮抬起事件
            EventTrigger.Entry up = new EventTrigger.Entry();
            up.eventID = EventTriggerType.PointerUp;
            up.callback.AddListener(upAction);

            // 查找所有子物体,根据名称获取UI控件
            foreach (Transform t in this.GetComponentsInChildren<Transform>()){
              if(t.name.CompareTo("wave")==0)  //找到文字控件“波数”
              {
                  m_txt_wave = t.GetComponent<Text>();
                  SetWave(1); //设为第1波
              }
              else if(t.name.CompareTo("life")==0)  //找到文字控件“生命”
              {
                  m_txt_life = t.GetComponent<Text>();
                  m_txt_life.text = string.Format("生命:<color=yellow>{0}</color>", m_life);
              }
              else if(t.name.CompareTo("point")==0)  //找到文字控件“铜钱”
              {
                  m_txt_point = t.GetComponent<Text>();
                  m_txt_point.text = string.Format("铜钱:<color=yellow>{0}</color>", m_point);
              }
            else if (t.name.CompareTo("but_try") == 0) //找到按钮控件“重新游戏”
            {
                m_but_try = t.GetComponent<Button>();
                // 重新游戏按钮
                m_but_try.onClick.AddListener( delegate(){
                  SceneManager.LoadScene(SceneManager.GetActiveScene().name);
                });
                // 默认隐藏重新游戏按钮
                m_but_try.gameObject.SetActive(false);

            }
            else if(t.name.Contains("but_player"))    //找到按钮控件“创建防守单位”
            {
                // 给防守单位按钮添加按钮事件
                EventTrigger trigger = t.gameObject.AddComponent<EventTrigger>();
                trigger.triggers = new List<EventTrigger.Entry>();
                trigger.triggers.Add(down);
                trigger.triggers.Add(up);
            }
        }
      }
      // 更新文字控件“波数”
      public void SetWave(int wave)
      {
        m_wave= wave;
        m_txt_wave.text = string.Format("波数:<color=yellow>{0}/{1}</color>", m_wave, m_waveMax);
      }
      // 更新文字控件“生命”
      public void SetDamage(int damage)
      {
        m_life -= damage;
        if (m_life <= 0) {
            m_life = 0;
            m_but_try.gameObject.SetActive(true);   //显示重新游戏按钮
        }
        m_txt_life.text = string.Format("生命:<color=yellow>{0}</color>", m_life);
      }

      // 更新文字控件“铜钱”
      public bool SetPoint(int point)
      {
        if(m_point+point<0)      // 如果铜钱数量不够
            return false;
                  m_point += point;
                  m_txt_point.text = string.Format("铜钱:<color=yellow>{0}</color>", m_point);
                  return true;
              }

              // 按下“创建防守单位按钮”
              void OnButCreateDefenderDown(BaseEventData data)
              {
                  m_isSelectedButton = true;
              }

              // 抬起“创建防守单位按钮”
              void OnButCreateDefenderUp( BaseEventData data )
              {
                  GameObject go = data.selectedObject;
              // 此处代码将在后面步骤补充
              }
            }

在Start函数中,我们先定义了按钮的事件,然后通过查找所有子物体的名称找到相应的UI控件进行初始化处理,对Text文字控件,赋予初始的波数、生命和铜钱数值。

因为在游戏开始时我们不希望看到重新游戏按钮,所以调用gameObject.SetActive(false)方法将该按钮隐藏,当游戏结束时再显示该按钮重新游戏。

对于创建防守单位的按钮,我们分别定义了按下和抬起两个事件,当按下按钮的时候,获得要创建的对象,抬起按钮时在选定位置创建防守单位,不过当前这些按钮事件的回调函数是空的,还没做什么事情。