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 () {
        
    }
}

 

posted @ 2018-08-20 00:03  Cynical丶Gary  阅读(2709)  评论(0编辑  收藏  举报