Unity3D_(游戲)卡牌03_選關界面


 

 

啟動屏界面、主菜單界面、選關界面、游戲界面

 

卡牌01_啟動屏界面  傳送門

卡牌02_主菜單界面  傳送門

卡牌03_選關界面   傳送門

卡牌04_游戲界面     傳送門

 

 

 選關界面效果

  (鼠標放在不同關卡上顯示不同的關卡提示信息點擊關卡按鈕時候出現短暫粉紅色點擊效果點擊返回主菜單游戲回到主菜單界面點擊游戲關卡進入游戲界面)

  

  不同游戲主題顯示不同數量的關卡,用到了游戲數據管理類,不同游戲主題顯示的卡牌不同

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DataMgr {
    private static DataMgr ins = null;

    public THEME_ID themeId;

    //某一主題所有關卡數據
    public LevelData levelData;
    public int levelId;             //進入游戲前,保存當前選擇的關卡id
    public LevelInfo levelInfo;     //當前關卡信息

    private DataMgr()
    {
        //將構造函數設置為私有,這樣避免外部創建類的實例,只能通過Instance()來獲取數據管理類的實例
    }

    public static DataMgr Instance()
    {
        if(ins == null)
        { 
            ins = new DataMgr();
        }
        return ins;
    }

    public LevelData InitLevelData(THEME_ID id)
    {
        levelData = null;
        switch (id)
        {
            case THEME_ID.Logo:
                levelData = Resources.Load<LevelData>("Prefabs/data/LevelDataLogo");
                break;
            case THEME_ID.Student:
                levelData = Resources.Load<LevelData>("Prefabs/data/LevelDataStudent");
                break;
            default:
                levelData = Resources.Load<LevelData>("Prefabs/data/LevelDataLogo");
                break;
        }
        return levelData; 
    }
}
DataMgr.class (數據管理類)

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;


public enum THEME_ID
{
    Logo,
    Student
}

public class Scene_MainMenu : MonoBehaviour {

    // Use this for initialization
    void Start () {
        GameObject.Find("LogoBtn").GetComponent<Button>().onClick.AddListener(()=>{ OnClickThemeBtn(THEME_ID.Logo); });
        GameObject.Find("StudentBtn").GetComponent<Button>().onClick.AddListener(() => { OnClickThemeBtn(THEME_ID.Student); });
        GameObject.Find("CloseBtn").GetComponent<Button>().onClick.AddListener(() => { OnCloseApp(); });
    }
    
    // Update is called once per frame
    void Update () {
       
    }

    void OnClickThemeBtn(THEME_ID theme)
    {
        SceneManager.LoadScene("SelectLevel");
        DataMgr.Instance().themeId = theme;
    }

    //退出程序
    void OnCloseApp()
    {
        Application.Quit();
    }
 
}
Scene_MainMenu.cs (關卡場景腳本)

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;


//選關界面,每一個關卡按鈕單元
public class LevelItemCell : MonoBehaviour ,IPointerEnterHandler,IPointerExitHandler,
        IPointerDownHandler,IPointerUpHandler,IPointerClickHandler{
    public RectTransform numTrans;
    public GameObject LockObj;
    public GameObject pressObj;

    //[HideInInspector]

    public int id;      //每個單元對應的關卡id(從1開始)
    public LevelManager lvlMgr;

    LevelInfo levelInfo;

    //點擊按鈕,跳轉到游戲界面
    public void OnPointerClick(PointerEventData eventData)
    {
        DataMgr.Instance().levelId = id;
        DataMgr.Instance().levelInfo = levelInfo;
        SceneManager.LoadScene("Gameplay");
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        pressObj.SetActive(true);
    }

    //當鼠標進入本單元矩形區域,顯示當前關卡描述
    public void OnPointerEnter(PointerEventData eventData)
    {
        lvlMgr.SetLevelDesc(levelInfo.desc);

    }

    public void OnPointerExit(PointerEventData eventData)
    {
        lvlMgr.SetLevelDesc("關卡信息");
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        pressObj.SetActive(false);
    }

    private void Awake()
    {
        LockObj.SetActive(false);
        pressObj.SetActive(false);
    }

    // Use this for initialization
    void Start () {
        float scale = 2;
        //初始化關卡數字顯示
        if (id < 10)
        {
            //完全用代碼動態創建一個Image對象,並作為num的子節點
            GameObject obj = new GameObject("num1",typeof(Image));
            RectTransform rtf = obj.GetComponent<RectTransform>();
            rtf.SetParent(numTrans);
            //設置數字
            Image img = obj.GetComponent<Image>();
            img.sprite = lvlMgr.spr_nums[id];
            img.SetNativeSize();    //圖片原始尺寸
            rtf.localScale = new Vector3(2,2,1);
            rtf.localPosition = Vector3.zero;

        }
        else if (id<100)
        {
            //十位數
            GameObject obj = new GameObject("num1", typeof(Image));
            RectTransform rtf = obj.GetComponent<RectTransform>();
            rtf.SetParent(numTrans);
            //設置數字
            Image img = obj.GetComponent<Image>();
            img.sprite = lvlMgr.spr_nums[id/10];
            img.SetNativeSize();    //圖片原始尺寸
            rtf.localScale = new Vector3(2, 2, 1);
            rtf.localPosition = new Vector3(-scale * rtf.rect.width/2-1,0,0);

            //個位數
            GameObject obj2 = new GameObject("num2", typeof(Image));
            RectTransform rtf2 = obj2.GetComponent<RectTransform>();
            rtf2.SetParent(numTrans);
            //設置數字
            Image img2 = obj2.GetComponent<Image>();
            img2.sprite = lvlMgr.spr_nums[id % 10];
            img2.SetNativeSize();    //圖片原始尺寸
            rtf2.localScale = new Vector3(2, 2, 1);
            rtf2.localPosition = new Vector3(scale * rtf2.rect.width / 2 + 1, 0, 0);
        }
        levelInfo = DataMgr.Instance().levelData.levels[id - 1];
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}
LevelItemCell.cs (每一個關卡按鈕單元腳本)

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
using UnityEngine.SceneManagement;

//用來管理所有關卡按鈕
//根據我們關卡數據定義,判斷一共多少個關卡按鈕。LevelManager來創建LevelPanelCell表格單元,LevelPanelCell表格單元是LevelItemCell
public class LevelManager : MonoBehaviour
{

    int totalCount = 0; //臨時測試,一共18關
    readonly int ITEM_COUNT_PAGE = 15;  //每一頁顯示15個關卡
    readonly float PANEL_SPACE = 10f;
    readonly float MOVE_TIME = 0.5f;

    public RectTransform contenTrans;
    public Sprite[] spr_nums;

  

    float panelCellOffset;
    int pageCount;

    GameObject levelPanelCellPreb;
    GameObject levelItemCellPreb;
    Text levelDescTxt;

    float pointerDownTimeBak;
    float pointerDownX;

    int pageIdx;

    public void Awake()
    {
        levelPanelCellPreb = Resources.Load<GameObject>("Prefabs/SelectLevel/LevelPanelCell");
        levelItemCellPreb = Resources.Load("Prefabs/SelectLevel/LevelItemCell") as GameObject;
        levelDescTxt = GameObject.Find("LevelDesc/text").GetComponent<Text>();

        GameObject.Find("BackMainMenu").GetComponent<Button>().onClick.AddListener(()=> { OnBackMainMenuBtn(); });

        DataMgr.Instance().InitLevelData(DataMgr.Instance().themeId);
        totalCount = DataMgr.Instance().levelData.levels.Length;    //根據關卡數據表的個數,動態設置單元數量
    }

    // Use this for initialization
    void Start()
    {
        //計算panel的偏移
        panelCellOffset = contenTrans.rect.width + PANEL_SPACE;
        //計算出一共需要多少頁
        pageCount = Mathf.CeilToInt((float)totalCount / ITEM_COUNT_PAGE);
        //當前顯示的第幾頁表格panel,從0開始
        pageIdx = 0;

        for (int i = 0; i < pageCount; i++)
        {
            CreateLevelPanclCell(i);
        }
    }

    // Update is called once per frame
    void Update()
    {
        //按下時記錄鼠標當前位置
        if (Input.GetMouseButtonDown(0))
        {
            pointerDownTimeBak = Time.time;
            pointerDownX = Input.mousePosition.x;
        }

        if (Input.GetMouseButtonUp(0))
        {
            //模擬滑動事件,假定很短時間的滑動
            if (Time.time - pointerDownTimeBak < 0.5f)
            {
                float offsetX = Input.mousePosition.x - pointerDownX;
                //向左滑動鼠標,並超過一定距離
                if (offsetX < -200 && pageIdx < pageCount - 1)
                {
                    //向左滑動鼠標,並超過一段距離
                    pageIdx++;
                    //執行所有表格面板向左平滑滑動
                    //0.5秒對自身左邊疊加量,向左移動一段距離
                    contenTrans.DOBlendableLocalMoveBy(new Vector3(-panelCellOffset, 0, 0), MOVE_TIME);

                }
                else if (offsetX > 200 && pageIdx > 0)
                {
                    //向右滑動鼠標,並超過一段距離
                    pageIdx--;
                    //執行所有表格面板向右平滑滑動
                    //0.5秒對自身左邊疊加量,向右移動一段距離
                    contenTrans.DOBlendableLocalMoveBy(new Vector3(panelCellOffset, 0, 0), MOVE_TIME);
                }
            }
        }
    }

    //創建表格panel,從0開始編號
    void CreateLevelPanclCell(int pageInx)
    {
        GameObject panelObj = Instantiate(levelPanelCellPreb, contenTrans);
        RectTransform panelTrans = panelObj.GetComponent<RectTransform>();
        panelTrans.anchoredPosition = new Vector2(panelCellOffset * pageInx, 0);

        //確定本業 中具有的關卡元素個數
        int startId = ITEM_COUNT_PAGE * pageInx;
        //本業需要顯示按鈕的個數
         int count = totalCount - startId;

        if (count > ITEM_COUNT_PAGE)
        {
            count = ITEM_COUNT_PAGE;
        }

        //創建本頁中所有關卡按鈕
        for (int i = 0; i < count; i++)
        {
            //創建每一個關卡的按鈕單元
            GameObject itemObj = Instantiate(levelItemCellPreb, panelTrans);

            //這一段cell相關調用,實在Start()之前執行的
            LevelItemCell cell = itemObj.GetComponent<LevelItemCell>();
            cell.id = startId + i + 1;      //設置每個單元的關卡編號
            cell.lvlMgr = this;
            itemObj.name = cell.id.ToString();

        }

    }

    //設置關卡描述
    public void SetLevelDesc(string content)
    {
        levelDescTxt.text = content;
    }

    void OnBackMainMenuBtn()
    {
        SceneManager.LoadScene("MainMenu");
    }
}
LevelManager.cs (游戲管理腳本)

 

 

實現過程

 

 

選關游戲界面

 

  新建畫布,添加背景,設置標題,增加選關區域范圍

  選關區域使用純白色作為背景(修改其透明度值),調整選關區域位置

 

  選關區域下方添加關卡信息(Panel默認是透明)

 

  LevelManager下方創建游戲空物體對象(Content),添加Panel,Panel上添加Grid Layout Group表格布局插件

 

  Fixed Column Count 固定行

    Constraint Count 每行固定最大值為5個單元表格

 

  利用組格插件好處:更方便實現動態添加選項關卡

  

LevelItemCell游戲單個關卡(點擊關卡時的顏色)

   動態生成關卡為未解鎖狀態

  

  

  點擊關卡時狀態

  

  

  關卡解鎖狀態

  

 

 

  添加Image覆蓋LevelItemCell選關單元,調整透明度(改名lock,未解鎖關卡時的顏色)

  同點擊鼠標讓關卡變色一個原理

 

  將LevelItemCell設置為預設體,使關卡能動態創建(業務與開發分離)

 

  添加腳本LevelItemCell並掛到預設體LevelItemCell上(腳本與預設體同名看起來方便)

  掛載完Apply更新,添加到源預設體上~

 

  同理將LevelPanelCell也設置為預設體,動態創建一頁關卡后會再動態創建關卡頁

  

 

  添加腳本LevelManager,掛載到LevelManager控件上

 

   LevelManager用來管理所有關卡按鈕

  LevelManager腳本根據我們關卡數據定義,判斷一共多少個關卡按鈕。LevelManager來創建LevelPanelCell表格單元,LevelPanelCell表格單元是LevelItemCell

 

  將Content關卡頁面綁定到LevelManager關卡頁面范圍上

      public  RectTransform contenTrans;

 

  計算panel的偏移

      readonly float PANEL_SPACE = 10f;   

      panelCellffset = contenTrans.rect.width + PANEL_SPACE;

 

  計算出一共需要多少頁

      int totalCount = 18; //臨時測試,一共18關
      readonly int ITEM_COUNT_PAGE = 15;  //每一頁顯示15個關卡
      readonly float PANEL_SPACE = 10f;  

      pageCount = Mathf.CeilToInt((float)totalCount / ITEM_COUNT_PAGE);

  Mathf.CeilToInt()上取整(Mathf.CeilToInt(1.5)、Mathf.CeilToInt(2.2)=3)

  

  獲得游戲控件UI

public void Awake()
    {
        levelPanelCellPreb = Resources.Load<GameObject>("Prefabs/SelectLevel/LevelPanelCell");
        levelItemCellPreb = Resources.Load("Prefabs/SelectLevel/LevelItemCell") as GameObject;
        levelDescTxt = GameObject.Find("LevelDesc/text").GetComponent<Text>();
    }

 

  創建表格panel,從0開始編號

void CreateLevelPanclCell(int pageInx)
    {
        GameObject panelObj = Instantiate(levelPanelCellPreb,contenTrans);
        RectTransform panelTrans = panelObj.GetComponent<RectTransform>();
        panelTrans.anchoredPosition = new Vector2(panelCellOffset * pageInx, 0);

        //確定本業 中具有的關卡元素個數
        int startId = ITEM_COUNT_PAGE * pageInx;
        //本業需要顯示按鈕的個數
        int count = totalCount - startId;

        if (count > ITEM_COUNT_PAGE)
        {
            count = ITEM_COUNT_PAGE;
        }

        //創建本頁中所有關卡按鈕
        for(int i =0;i<count;i++)
        {
            //創建每一個關卡的按鈕單元
            GameObject itemObj = Instantiate(levelItemCellPreb,panelTrans);

            LevelItemCell cell = itemObj.GetComponent<LevelItemCell>();
            cell.id = startId+i+1;
            cell.lvlMgr = this;
            itemObj.name = cell.id.ToString();

        }

    }

 

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


//選關界面,每一個關卡按鈕單元
public class LevelItemCell : MonoBehaviour {

    public int id;      //每個單元對應的關卡id(從1開始)
    public LevelManager lvlMgr;

    // Use this for initialization
    void Start () {
        
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}
LevelItemCell.cs

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

//用來管理所有關卡按鈕
//根據我們關卡數據定義,判斷一共多少個關卡按鈕。LevelManager來創建LevelPanelCell表格單元,LevelPanelCell表格單元是LevelItemCell
public class LevelManager : MonoBehaviour {

    int totalCount = 18; //臨時測試,一共18關
    readonly int ITEM_COUNT_PAGE = 15;  //每一頁顯示15個關卡
    readonly float PANEL_SPACE = 10f;   

    public  RectTransform contenTrans;
    float panelCellOffset;
    int pageCount;

    GameObject levelPanelCellPreb;
    GameObject levelItemCellPreb;
    Text levelDescTxt;


    //int pageIdx;

    public void Awake()
    {
        levelPanelCellPreb = Resources.Load<GameObject>("Prefabs/SelectLevel/LevelPanelCell");
        levelItemCellPreb = Resources.Load("Prefabs/SelectLevel/LevelItemCell") as GameObject;
        levelDescTxt = GameObject.Find("LevelDesc/text").GetComponent<Text>();


    }

    // Use this for initialization
    void Start () {
        //計算panel的偏移
        panelCellOffset = contenTrans.rect.width + PANEL_SPACE;
        //計算出一共需要多少頁
        pageCount = Mathf.CeilToInt((float)totalCount / ITEM_COUNT_PAGE);

       // pageIdx = 0;
        for (int i = 0; i < pageCount; i++)
        {
            CreateLevelPanclCell(i);
        }
      }
    
      // Update is called once per frame
    void Update () {
            
    }

    //創建表格panel,從0開始編號
    void CreateLevelPanclCell(int pageInx)
    {
        GameObject panelObj = Instantiate(levelPanelCellPreb,contenTrans);
        RectTransform panelTrans = panelObj.GetComponent<RectTransform>();
        panelTrans.anchoredPosition = new Vector2(panelCellOffset * pageInx, 0);

        //確定本業 中具有的關卡元素個數
        int startId = ITEM_COUNT_PAGE * pageInx;
        //本業需要顯示按鈕的個數
        int count = totalCount - startId;

        if (count > ITEM_COUNT_PAGE)
        {
            count = ITEM_COUNT_PAGE;
        }

        //創建本頁中所有關卡按鈕
        for(int i =0;i<count;i++)
        {
            //創建每一個關卡的按鈕單元
            GameObject itemObj = Instantiate(levelItemCellPreb,panelTrans);

            LevelItemCell cell = itemObj.GetComponent<LevelItemCell>();
            cell.id = startId+i+1;
            cell.lvlMgr = this;
            itemObj.name = cell.id.ToString();

        }

    }

    //設置關卡描述
    void SetLevelDesc(string content)
    {
        levelDescTxt.text = content;
    }
}
LevelManager.cs

 

  因為我們默認初始化游戲18個關卡,一個選關界面存放15個關卡

  所有關卡時出現出現兩個選關界面

  為了只出現一個選關界面

  使用Unity提供的Mask插件

  Mask插件:提供給需要Mask的圖片修改渲染頂點,達到遮罩效果

 

  在LevelManager控件上添加Mask插件

 

 

整體滑動效果

 

  DOTween插件控制選關界面移動  下載:傳送門

 

  下載完后,把解壓的包,直接拖入工程 在unity 菜單欄 Tools—Demigiant—DOTween Utility Panel。點擊后,在右圖中點擊Setup DOTween… 工具會導入必要的庫。

 

滑動效果效果:

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;

//用來管理所有關卡按鈕
//根據我們關卡數據定義,判斷一共多少個關卡按鈕。LevelManager來創建LevelPanelCell表格單元,LevelPanelCell表格單元是LevelItemCell
public class LevelManager : MonoBehaviour {

    int totalCount = 18; //臨時測試,一共18關
    readonly int ITEM_COUNT_PAGE = 15;  //每一頁顯示15個關卡
    readonly float PANEL_SPACE = 10f;
    readonly float MOVE_TIME = 0.5f;

    public  RectTransform contenTrans;
    float panelCellOffset;
    int pageCount;

    GameObject levelPanelCellPreb;
    GameObject levelItemCellPreb;
    Text levelDescTxt;

    float pointerDownTimeBak;
    float pointerDownX;

    int pageIdx;

    public void Awake()
    {
        levelPanelCellPreb = Resources.Load<GameObject>("Prefabs/SelectLevel/LevelPanelCell");
        levelItemCellPreb = Resources.Load("Prefabs/SelectLevel/LevelItemCell") as GameObject;
        levelDescTxt = GameObject.Find("LevelDesc/text").GetComponent<Text>();
    }

    // Use this for initialization
    void Start () {
        //計算panel的偏移
        panelCellOffset = contenTrans.rect.width + PANEL_SPACE;
        //計算出一共需要多少頁
        pageCount = Mathf.CeilToInt((float)totalCount / ITEM_COUNT_PAGE);
        //當前顯示的第幾頁表格panel,從0開始
        pageIdx = 0;

        for (int i = 0; i < pageCount; i++)
        {
            CreateLevelPanclCell(i);
        }
      }
    
      // Update is called once per frame
    void Update () {
        //按下時記錄鼠標當前位置
        if (Input.GetMouseButtonDown(0))
        {
            pointerDownTimeBak = Time.time;
            pointerDownX = Input.mousePosition.x;
        }

        if(Input.GetMouseButtonUp(0))
        {
            //模擬滑動事件,假定很短時間的滑動
            if(Time.time - pointerDownTimeBak<0.5f)
            {
                float offsetX = Input.mousePosition.x - pointerDownX;
                //向左滑動鼠標,並超過一定距離
                if (offsetX < -200 && pageIdx<pageCount-1)
                {
                    //向左滑動鼠標,並超過一段距離
                    pageIdx++;
                    //執行所有表格面板向左平滑滑動
                    //0.5秒對自身左邊疊加量,向左移動一段距離
                    contenTrans.DOBlendableLocalMoveBy(new Vector3(-panelCellOffset, 0, 0), MOVE_TIME);

                }else if (offsetX>200&&pageIdx>0)
                {
                    //向右滑動鼠標,並超過一段距離
                    pageIdx--;
                    //執行所有表格面板向右平滑滑動
                    //0.5秒對自身左邊疊加量,向右移動一段距離
                    contenTrans.DOBlendableLocalMoveBy(new Vector3(panelCellOffset, 0, 0), MOVE_TIME);
                }
            }
        }
    }

    //創建表格panel,從0開始編號
    void CreateLevelPanclCell(int pageInx)
    {
        GameObject panelObj = Instantiate(levelPanelCellPreb,contenTrans);
        RectTransform panelTrans = panelObj.GetComponent<RectTransform>();
        panelTrans.anchoredPosition = new Vector2(panelCellOffset * pageInx, 0);

        //確定本業 中具有的關卡元素個數
        int startId = ITEM_COUNT_PAGE * pageInx;
        //本業需要顯示按鈕的個數
        int count = totalCount - startId;

        if (count > ITEM_COUNT_PAGE)
        {
            count = ITEM_COUNT_PAGE;
        }

        //創建本頁中所有關卡按鈕
        for(int i =0;i<count;i++)
        {
            //創建每一個關卡的按鈕單元
            GameObject itemObj = Instantiate(levelItemCellPreb,panelTrans);

            LevelItemCell cell = itemObj.GetComponent<LevelItemCell>();
            cell.id = startId+i+1;
            cell.lvlMgr = this;
            itemObj.name = cell.id.ToString();

        }

    }

    //設置關卡描述
    void SetLevelDesc(string content)
    {
        levelDescTxt.text = content;
    }
}
LevelManager.cs

 

  MOVE_TIME時間內選擇關卡向左邊的疊加量,向左移動一段距離

 contenTrans.DOBlendableLocalMoveBy(new Vector3(-panelCellOffset, 0, 0), MOVE_TIME);

 

  按下時記錄鼠標當前位置

if (Input.GetMouseButtonDown(0))
        {
            pointerDownTimeBak = Time.time;
            pointerDownX = Input.mousePosition.x;
        }

 

  松開鼠標時觸發事件

 if(Input.GetMouseButtonUp(0))
        {
            //模擬滑動事件,假定很短時間的滑動
            if(Time.time - pointerDownTimeBak<0.5f)
            {
                float offsetX = Input.mousePosition.x - pointerDownX;
                //向左滑動鼠標,並超過一定距離
                if (offsetX < -200 && pageIdx<pageCount-1)
                {
                    //向左滑動鼠標,並超過一段距離
                    pageIdx++;
                    //執行所有表格面板向左平滑滑動
                    //0.5秒對自身左邊疊加量,向左移動一段距離
                    contenTrans.DOBlendableLocalMoveBy(new Vector3(-panelCellOffset, 0, 0), MOVE_TIME);

                }else if (offsetX>200&&pageIdx>0)
                {
                    //向右滑動鼠標,並超過一段距離
                    pageIdx--;
                    //執行所有表格面板向右平滑滑動
                    //0.5秒對自身左邊疊加量,向右移動一段距離
                    contenTrans.DOBlendableLocalMoveBy(new Vector3(panelCellOffset, 0, 0), MOVE_TIME);
                }
            }
        }

 

 

代碼創建關卡數字

 

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


//選關界面,每一個關卡按鈕單元
public class LevelItemCell : MonoBehaviour {
    public RectTransform numTrans;
    public int id;      //每個單元對應的關卡id(從1開始)
    public LevelManager lvlMgr;

    private void Awake()
    {
        
    }

    // Use this for initialization
    void Start () {
        float scale = 2;
        //初始化關卡數字顯示
        if (id < 10)
        {
            //完全用代碼動態創建一個Image對象,並作為num的子節點
            GameObject obj = new GameObject("num1",typeof(Image));
            RectTransform rtf = obj.GetComponent<RectTransform>();
            rtf.SetParent(numTrans);
            //設置數字
            Image img = obj.GetComponent<Image>();
            img.sprite = lvlMgr.spr_nums[id];
            img.SetNativeSize();    //圖片原始尺寸
            rtf.localScale = new Vector3(2,2,1);
            rtf.localPosition = Vector3.zero;

        }
        else if (id<100)
        {
            //十位數
            GameObject obj = new GameObject("num1", typeof(Image));
            RectTransform rtf = obj.GetComponent<RectTransform>();
            rtf.SetParent(numTrans);
            //設置數字
            Image img = obj.GetComponent<Image>();
            img.sprite = lvlMgr.spr_nums[id/10];
            img.SetNativeSize();    //圖片原始尺寸
            rtf.localScale = new Vector3(2, 2, 1);
            rtf.localPosition = new Vector3(-scale * rtf.rect.width/2-1,0,0);

            //個位數
            GameObject obj2 = new GameObject("num2", typeof(Image));
            RectTransform rtf2 = obj2.GetComponent<RectTransform>();
            rtf2.SetParent(numTrans);
            //設置數字
            Image img2 = obj2.GetComponent<Image>();
            img2.sprite = lvlMgr.spr_nums[id % 10];
            img2.SetNativeSize();    //圖片原始尺寸
            rtf2.localScale = new Vector3(2, 2, 1);
            rtf2.localPosition = new Vector3(scale * rtf2.rect.width / 2 + 1, 0, 0);
        }
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}
LevelItemCell.cs

 

 

  num子節點下創建兩個Image控件存放數字

 

 

  定義Sprite[]數組,將圖片綁定上去

public Sprite[] spr_nums;

 

 

 

 

 

  用代碼動態創建一個Image對象,並作為num的子節點

       GameObject obj = new GameObject("num1",typeof(Image));
            RectTransform rtf = obj.GetComponent<RectTransform>();
            rtf.SetParent(numTrans);

 

  圖片原始尺寸

            img.SetNativeSize();

 

  圖片的縮放比例

 rtf.localScale = new Vector3(2,2,1);

 

 

  當id<10時,定義圖片放置的位置

 rtf.localPosition = Vector3.zero;

 

 

if (id < 10)
        {
            //完全用代碼動態創建一個Image對象,並作為num的子節點
            GameObject obj = new GameObject("num1",typeof(Image));
            RectTransform rtf = obj.GetComponent<RectTransform>();
            rtf.SetParent(numTrans);
            //設置數字
            Image img = obj.GetComponent<Image>();
            img.sprite = lvlMgr.spr_nums[id];
            img.SetNativeSize();    //圖片原始尺寸
            rtf.localScale = new Vector3(2,2,1);
            rtf.localPosition = Vector3.zero;

        }

 

 

 

 

  個位數位置

            img.SetNativeSize();    //圖片原始尺寸
            rtf.localScale = new Vector3(2, 2, 1);
            rtf.localPosition = new Vector3(-scale * rtf.rect.width/2-1,0,0);

 

  十位數位置

            img2.SetNativeSize();    //圖片原始尺寸
            rtf2.localScale = new Vector3(2, 2, 1);
            rtf2.localPosition = new Vector3(scale * rtf2.rect.width / 2 + 1, 0, 0);

 

 

   同理個位數,不同在於圖片擺放的位置

        else if (id<100)
        {
            //十位數
            GameObject obj = new GameObject("num1", typeof(Image));
            RectTransform rtf = obj.GetComponent<RectTransform>();
            rtf.SetParent(numTrans);
            //設置數字
            Image img = obj.GetComponent<Image>();
            img.sprite = lvlMgr.spr_nums[id/10];
            img.SetNativeSize();    //圖片原始尺寸
            rtf.localScale = new Vector3(2, 2, 1);
            rtf.localPosition = new Vector3(-scale * rtf.rect.width/2-1,0,0);

            //個位數
            GameObject obj2 = new GameObject("num2", typeof(Image));
            RectTransform rtf2 = obj2.GetComponent<RectTransform>();
            rtf2.SetParent(numTrans);
            //設置數字
            Image img2 = obj2.GetComponent<Image>();
            img2.sprite = lvlMgr.spr_nums[id % 10];
            img2.SetNativeSize();    //圖片原始尺寸
            rtf2.localScale = new Vector3(2, 2, 1);
            rtf2.localPosition = new Vector3(scale * rtf2.rect.width / 2 + 1, 0, 0);
        }

 

 

數據管理類

 

    unity除非特別指定,當切換到新場景時原場景中所有游戲對象都會銷毀。那么伴隨着掛在對象上的腳本也會銷毀。
    我們需要有一個類,能夠使各處都能夠便利訪問。並且這個類對象實例,只需要一個
Unity_單例模式

 

  第一個游戲主題只有18關

 

  第一個游戲主題有20關

  ( Unity引擎加載場景有點慢(´・_・`)  )

 

 

  某一主題所有關卡數據

    public LevelData levelData;

 

  點擊不同主題按鈕選擇不同主題的關卡

    void OnClickThemeBtn(THEME_ID theme)
    {
        SceneManager.LoadScene("SelectLevel");
        DataMgr.Instance().themeId = theme;
    }

 

    public LevelData InitLevelData(THEME_ID id)
    {
        levelData = null;
        switch (id)
        {
            case THEME_ID.Logo:
                levelData = Resources.Load<LevelData>("Prefabs/data/LevelDataLogo");
                break;
            case THEME_ID.Student:
                levelData = Resources.Load<LevelData>("Prefabs/data/LevelDataStudent");
                break;
            default:
                levelData = Resources.Load<LevelData>("Prefabs/data/LevelDataLogo");
                break;
        }
        return levelData; 
    }

 

 

關卡單元實現

 

  添加兩個游戲主鍵的引用

    public GameObject LockObj;
    public GameObject pressObj;

 

  點擊按鈕時關卡單元變色Image和鎖的Image添加上去

 

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;


//選關界面,每一個關卡按鈕單元
public class LevelItemCell : MonoBehaviour ,IPointerEnterHandler,IPointerExitHandler,
        IPointerDownHandler,IPointerUpHandler,IPointerClickHandler{
    public RectTransform numTrans;
    public GameObject LockObj;
    public GameObject pressObj;

    //[HideInInspector]

    public int id;      //每個單元對應的關卡id(從1開始)
    public LevelManager lvlMgr;

    LevelInfo levelInfo;

    //點擊按鈕,跳轉到游戲界面
    public void OnPointerClick(PointerEventData eventData)
    {
        DataMgr.Instance().levelId = id;
        DataMgr.Instance().levelInfo = levelInfo;
        SceneManager.LoadScene("Gameplay");
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        pressObj.SetActive(true);
    }

    //當鼠標進入本單元矩形區域,顯示當前關卡描述
    public void OnPointerEnter(PointerEventData eventData)
    {
        lvlMgr.SetLevelDesc(levelInfo.desc);

    }

    public void OnPointerExit(PointerEventData eventData)
    {
        lvlMgr.SetLevelDesc("關卡信息");
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        pressObj.SetActive(false);
    }

    private void Awake()
    {
        LockObj.SetActive(false);
        pressObj.SetActive(false);
    }

    // Use this for initialization
    void Start () {
        float scale = 2;
        //初始化關卡數字顯示
        if (id < 10)
        {
            //完全用代碼動態創建一個Image對象,並作為num的子節點
            GameObject obj = new GameObject("num1",typeof(Image));
            RectTransform rtf = obj.GetComponent<RectTransform>();
            rtf.SetParent(numTrans);
            //設置數字
            Image img = obj.GetComponent<Image>();
            img.sprite = lvlMgr.spr_nums[id];
            img.SetNativeSize();    //圖片原始尺寸
            rtf.localScale = new Vector3(2,2,1);
            rtf.localPosition = Vector3.zero;

        }
        else if (id<100)
        {
            //十位數
            GameObject obj = new GameObject("num1", typeof(Image));
            RectTransform rtf = obj.GetComponent<RectTransform>();
            rtf.SetParent(numTrans);
            //設置數字
            Image img = obj.GetComponent<Image>();
            img.sprite = lvlMgr.spr_nums[id/10];
            img.SetNativeSize();    //圖片原始尺寸
            rtf.localScale = new Vector3(2, 2, 1);
            rtf.localPosition = new Vector3(-scale * rtf.rect.width/2-1,0,0);

            //個位數
            GameObject obj2 = new GameObject("num2", typeof(Image));
            RectTransform rtf2 = obj2.GetComponent<RectTransform>();
            rtf2.SetParent(numTrans);
            //設置數字
            Image img2 = obj2.GetComponent<Image>();
            img2.sprite = lvlMgr.spr_nums[id % 10];
            img2.SetNativeSize();    //圖片原始尺寸
            rtf2.localScale = new Vector3(2, 2, 1);
            rtf2.localPosition = new Vector3(scale * rtf2.rect.width / 2 + 1, 0, 0);
        }
        levelInfo = DataMgr.Instance().levelData.levels[id - 1];
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}
LevelItemCell.cs

 

   初始化時點擊單元關卡(粉紅色效果)和鎖(效果)不可見

   private void Awake()
    {
        LockObj.SetActive(false);
        pressObj.SetActive(false);
    }

 

  點擊按鈕事件

  //點擊按鈕,跳轉到游戲界面
    public void OnPointerClick(PointerEventData eventData)
    {
        DataMgr.Instance().levelId = id;
        DataMgr.Instance().levelInfo = levelInfo;
        SceneManager.LoadScene("Gameplay");
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        pressObj.SetActive(true);
    }

    //當鼠標進入本單元矩形區域,顯示當前關卡描述
    public void OnPointerEnter(PointerEventData eventData)
    {
        lvlMgr.SetLevelDesc(levelInfo.desc);

    }

    public void OnPointerExit(PointerEventData eventData)
    {
        lvlMgr.SetLevelDesc("關卡信息");
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        pressObj.SetActive(false);
    }

 

 

public class LevelItemCell : MonoBehaviour ,IPointerEnterHandler,IPointerExitHandler,
        IPointerDownHandler,IPointerUpHandler,IPointerClickHandler{
    public RectTransform numTrans;
    public GameObject LockObj;
    public GameObject pressObj;

    //[HideInInspector]

    public int id;      //每個單元對應的關卡id(從1開始)
    public LevelManager lvlMgr;

    LevelInfo levelInfo;

    //點擊按鈕,跳轉到游戲界面
    public void OnPointerClick(PointerEventData eventData)
    {
        DataMgr.Instance().levelId = id;
        DataMgr.Instance().levelInfo = levelInfo;
        SceneManager.LoadScene("Gameplay");
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        pressObj.SetActive(true);
    }

    //當鼠標進入本單元矩形區域,顯示當前關卡描述
    public void OnPointerEnter(PointerEventData eventData)
    {
        lvlMgr.SetLevelDesc(levelInfo.desc);

    }

    public void OnPointerExit(PointerEventData eventData)
    {
        lvlMgr.SetLevelDesc("關卡信息");
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        pressObj.SetActive(false);
    }

    private void Awake()
    {
        LockObj.SetActive(false);
        pressObj.SetActive(false);
    }

    // Use this for initialization
    void Start () {
        float scale = 2;
        //初始化關卡數字顯示
        if (id < 10)
        {
            //完全用代碼動態創建一個Image對象,並作為num的子節點
            GameObject obj = new GameObject("num1",typeof(Image));
            RectTransform rtf = obj.GetComponent<RectTransform>();
            rtf.SetParent(numTrans);
            //設置數字
            Image img = obj.GetComponent<Image>();
            img.sprite = lvlMgr.spr_nums[id];
            img.SetNativeSize();    //圖片原始尺寸
            rtf.localScale = new Vector3(2,2,1);
            rtf.localPosition = Vector3.zero;

        }
        else if (id<100)
        {
            //十位數
            GameObject obj = new GameObject("num1", typeof(Image));
            RectTransform rtf = obj.GetComponent<RectTransform>();
            rtf.SetParent(numTrans);
            //設置數字
            Image img = obj.GetComponent<Image>();
            img.sprite = lvlMgr.spr_nums[id/10];
            img.SetNativeSize();    //圖片原始尺寸
            rtf.localScale = new Vector3(2, 2, 1);
            rtf.localPosition = new Vector3(-scale * rtf.rect.width/2-1,0,0);

            //個位數
            GameObject obj2 = new GameObject("num2", typeof(Image));
            RectTransform rtf2 = obj2.GetComponent<RectTransform>();
            rtf2.SetParent(numTrans);
            //設置數字
            Image img2 = obj2.GetComponent<Image>();
            img2.sprite = lvlMgr.spr_nums[id % 10];
            img2.SetNativeSize();    //圖片原始尺寸
            rtf2.localScale = new Vector3(2, 2, 1);
            rtf2.localPosition = new Vector3(scale * rtf2.rect.width / 2 + 1, 0, 0);
        }
        levelInfo = DataMgr.Instance().levelData.levels[id - 1];
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM