Unity3D开发飞盘射击案例之游戏管理器(十八)

本节要点

1.UI 界面搭建

1.开始界面 UI

新建一个“StartUI”空物体,在这个物体下创建子物体,用于 UI 的显示。

游戏名称,游戏玩法,开始游戏按钮。

2.游戏界面 UI

新建新建一个“GameUI”空物体,在这个物体下创建子物体,用于 UI 的显示。

时间,分数。


3.结束界面 UI

新建一个“EndUI”空物体,在这个物体下创建子物体,用于 UI 的显示。

分数,重新开始按钮。



2.游戏管理器

1.游戏管理器的作用

创建一个叫做“GameManager”的脚本,管理整个游戏的流程逻辑。




2.游戏管理器框架编写

①创建当前游戏状态枚举,当前游戏只有三种状态:开始,游戏中,结束。

②查找获取三组 UI 的引用,并控制它们的显示次序。

③定义一个字段存储当前的游戏状态。

④定义一个切换游戏状态的方法。

⑤通过背景声音和 UI 演示状态切换的效果。


关键代码

Weapon

public class Weapon : MonoBehaviour {

    //手臂指向鼠标点击的位置
    //声明一个手臂位置的变量;
    private Transform m_transform;


    //利用射线去检测
    //声明一个射线的变量 声明一个存贮射线信息存贮的变量
    private Ray ray;
    private RaycastHit hit;


    //定义一个枪口位置的变量;
    private Transform m_Point;




    //设置特效 线渲染器属性组件 变量

   private LineRenderer m_LineRenderer;



    //设置特效的声音源 射击声
   private AudioSource m_AudioSource;

    
    void Start () {
        //将Transform 位置赋值
        m_transform=gameObject.GetComponent();

        //枪口位置赋值;
      //  m_Point = gameObject.transform.FindChild("Point").GetComponent(); 
        m_Point = m_transform.FindChild("Point");


        //特效渲染器组件位置赋值;关键语法  利用枪口的位置设置; 先将查找到的组件 linerenderer 存贮起来

      m_LineRenderer = m_Point.gameObject.GetComponent();


        //将声音源赋值;通过查找武器父类获得下面的射击声音源; 不要勾选paly on awake  和loop;
      m_AudioSource = gameObject.GetComponent();


    }
    
    
    void Update () {
    
        //使手臂朝向鼠标点击的位置;

        //接收射线的变量  利用摄像机获取射线并赋值;
        ray = Camera.main.ScreenPointToRay(Input.mousePosition);//从屏幕发射到鼠标点击的位置的射线;
        //进行物理检测 
        if (Physics.Raycast(ray, out hit))
        {
            //控制手臂的方向
            //检测成功后调用 游戏对象位置的  朝向 方法 lookat
           m_transform.LookAt(hit.point);//参数是碰撞点


            //检查是否有碰撞;
            //Debug.Log("Collider");
            //场景中没有任何碰撞体 或者打开场景的属性检查;所以手臂不会移动

            //因此 要添加网格碰撞器 选中 游戏物体 add component  加组件 mesh Collider; 
            //但是默认的有4千个顶点,ui设计的只有2千顶点的简模 所以用ui的添加碰撞器



            //成功测试后,发现手的旋转关节不对,就是手是手臂的中心点 可以定义一个父类来控制它 不要以为手臂的中心点来控制
            //建立一个父类,把之前的代码组件移除  设置好父类坐标,将脚本挂载到父类组件去


            //绘制枪口发射线  
           //与绘制射线方法相同 Debug.DrawRay();
          // Debug.DrawLine(m_transform.position,hit.point,Color.red);//参数1: 起始位置 参数2:射线碰撞的位置 参数3:颜色;


        //射线出发的位置不对 所以定义一个空物体存贮枪口的位置 transform
            //怎么查找父类下的组件呢?
           //gameObject.transform.Find("Point");
            //如果游戏对象下面有N个叫Point的组件呢;所以我们只要查找父类下的组件名称即可;
          // m_Point = gameObject.transform.FindChild("Point").GetComponent(); // 这是赋值过程,写到Start方法即可;

            //再次绘制射线;
           Debug.DrawLine(m_Point.position, hit.point, Color.red);


            //绘制特效线的位置;注意关键函数 
          m_LineRenderer.SetPosition(0,m_Point.position);//参数1:特效起始位置的下标 参数2:特效起始位置下标的位置 (枪口位置)
         m_LineRenderer.SetPosition(1,hit.point);//参数1:特效结束位置的下标 参数2:特效结束位置下标的位置 (射线碰撞点)



            //射线检测碰撞体后将飞盘击破
            //判断条件 碰撞体的标签并且按下鼠标左键
         if (hit.collider.tag=="FeiPan"&&Input.GetMouseButtonDown(0))
         {
             //如果射击到,就播放声音;在Start()中已赋值;
             m_AudioSource.Play();






             //通过碰撞到的子组件查找到父类 Transform
             Transform parent = hit.collider.gameObject.GetComponent().parent;//注意组件是单数



            //通过父类查找到子类下所有的Transform组件;得到的是一个数组

             Transform[] feiPans=parent.GetComponentsInChildren();//注意组件是复数


             //要实现往下掉落,必须动态添加刚体组件
             //通过for循环,Transform点出来符物体,然后添加刚体组件
             for (int i = 0; i ();


             }


             //18个组件掉落后一直掉落并没有销毁,必须把父物体销毁
             //2秒后,销毁父物体 通过transform 点出来 父物体组件 销毁的gameobject
             GameObject.Destroy(parent.gameObject,2.0f);

             
         }


        }



    }
}

FeiPanMannger

public class FeiPanMannger : MonoBehaviour {


    //定义一个游戏对象用来存贮预置体的;
    public GameObject prefab_feiPan;
    

    //定义一个飞盘的Transform组件 用来接收然后吧它设置成父类的组件
    private Transform m_Transform;

    void Start () {
     //协程
    //每隔2秒调用一次 注意关键语句 方法名为字符串 注意括号为英文半角格式;
        InvokeRepeating("CreateFeiPan",2.0f,2.0f);



        //将m_Transform组件赋值;
        m_Transform=gameObject.GetComponent();
    }

    /// 
    /// 创建生成飞盘;
    /// 
    void CreateFeiPan() { 
    
    
        //先获取飞盘的位置;
        //Vector3 pos = new Vector3(Random.Range(-4.0f,4.0f),Random.Range(0.5f,1.5f),Random.Range(4.0f,13.0f));

        ////实例化生成飞盘 
        //GameObject.Instantiate(prefab_feiPan,pos,Quaternion.identity);


        //发现以上方法生成太慢;一次生成3个;

        for (int i = 0; i < 3; i++)
        {
            Vector3 pos = new Vector3(Random.Range(-4.0f,4.0f),Random.Range(1.0f,3.5f),Random.Range(8.0f,13.0f));
          
            //GameObject.Instantiate(prefab_feiPan,pos,Quaternion.identity);
            //将实例化的飞盘存贮起来
            GameObject go = GameObject.Instantiate(prefab_feiPan, pos, Quaternion.identity) as GameObject;
            //将游戏对象下获得Transform组件 设置成父类组件 参数:m_Transform;
            //给生成的飞盘设置成一个父物体;
            go.GetComponent().SetParent(m_Transform);
        }
    
    }

    void Update () {
    
    }
}

GameMannger

public class GameMannger : MonoBehaviour {

   /// 
   /// 游戏三种状态
   /// 
    public enum GameState { 
        START,
        GAME,
        END   
    }


    //定义三个游戏对象变量来接收项目中3个游戏UI;
    //存贮3个UI界面的引用;
    private GameObject m_StratUI;
    private GameObject m_GameUI;
    private GameObject m_EndUI;


    //存贮当前游戏的状态 关键词:GameState;就是枚举的类型 上面定义好的;
    private GameState gameState;



    //背景音乐管理 控制音乐只在游戏进行中播放,其他状态不播放;
    private AudioSource m_BG_AudioSource;




    void Start () {
        //赋值过程 通过Find方法去查找并赋值;
        //通过查找持有三个UI的引用
        m_StratUI = GameObject.Find("StratUI");
        m_GameUI = GameObject.Find("GameUI");
        m_EndUI = GameObject.Find("EndUI");

        //将背景音乐赋值 通过查找持有背景音乐的引用
       // m_BG_AudioSource = GameObject.Find("ShooterWeapon") as AudioSource; 只能查找组件,不能直查找组件里的内容;
        m_BG_AudioSource=GameObject.Find("Main Camera").GetComponent();
        
        //只保留游戏开始界面,其他两个界面隐藏;
        //m_GameUI.SetActive(false);
        //m_EndUI.SetActive(false);


        //传递游戏状态
       // ChangeGameState(GameState.START);//开始
        ChangeGameState(GameState.GAME);//游戏进行中
      //  ChangeGameState(GameState.END);//结束;
    




    }
    
    /// 
    /// 改变游戏的状态
    /// 
    ///  当前状态
    public void ChangeGameState(GameState state){
    
        //存贮传过来的游戏状态
        gameState=state;

       //开始判断转过来的游戏状态;枚举类型
        if (gameState==GameState.START)     //游戏开始
        {
         
            //游戏开始时 游戏界面可用 其他两个界面隐藏;
            m_StratUI.SetActive(true);
            m_GameUI.SetActive(false);
            m_EndUI.SetActive(false);

            //游戏开始界面不播放

            m_BG_AudioSource.Stop();

        }else if (gameState==GameState.GAME)    //游戏进行中
        {
           m_StratUI.SetActive(false);
            m_GameUI.SetActive(true);
            m_EndUI.SetActive(false);

            //游戏进行中播放音乐
            m_BG_AudioSource.Play();

        }else if (gameState==GameState.END)                 //游戏结束
        {
           m_StratUI.SetActive(false);
            m_GameUI.SetActive(false);
            m_EndUI.SetActive(true);

            //游戏结束状态也不播放
            m_BG_AudioSource.Stop();
        }


    }
    

    void Update () {
    
    }
}

你可能感兴趣的:(Unity3D开发飞盘射击案例之游戏管理器(十八))