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<Transform>();

        //槍口位置賦值;
      //  m_Point = gameObject.transform.FindChild("Point").GetComponent<Transform>(); 
        m_Point = m_transform.FindChild("Point");


        //特效渲染器組件位置賦值;關鍵語法  利用槍口的位置設置; 先將查找到的組件 linerenderer 存貯起來

      m_LineRenderer = m_Point.gameObject.GetComponent<LineRenderer>();


        //將聲音源賦值;通過查找武器父類獲得下面的射擊聲音源; 不要勾選paly on awake  和loop;
      m_AudioSource = gameObject.GetComponent<AudioSource>();


    }
    
    
    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<Transform>(); // 這是賦值過程,寫到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<Transform>().parent;//注意組件是單數



            //通過父類查找到子類下所有的Transform組件;得到的是一個數組

             Transform[] feiPans=parent.GetComponentsInChildren<Transform>();//注意組件是復數


             //要實現往下掉落,必須動態添加剛體組件
             //通過for循環,Transform點出來符物體,然后添加剛體組件
             for (int i = 0; i <feiPans.Length; i++)
             {
                 //通過子物體組件尋找出父類添加剛體組件;模擬掉落效果;不用接收賦值;
                 feiPans[i].gameObject.AddComponent<Rigidbody>();


             }


             //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<Transform>();
    }

    /// <summary>
    /// 創建生成飛盤;
    /// </summary>
    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<Transform>().SetParent(m_Transform);
        }
    
    }

    void Update () {
    
    }
}

GameMannger

public class GameMannger : MonoBehaviour {

   /// <summary>
   /// 游戲三種狀態
   /// </summary>
    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<AudioSource>();
        
        //只保留游戲開始界面,其他兩個界面隱藏;
        //m_GameUI.SetActive(false);
        //m_EndUI.SetActive(false);


        //傳遞游戲狀態
       // ChangeGameState(GameState.START);//開始
        ChangeGameState(GameState.GAME);//游戲進行中
      //  ChangeGameState(GameState.END);//結束;
    




    }
    
    /// <summary>
    /// 改變游戲的狀態
    /// </summary>
    /// <param name="state"> 當前狀態</param>
    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 () {
    
    }
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容