启动屏界面、主菜单界面、选关界面、游戏界面

卡牌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;             //进入游戏前,保存当前选择的关卡idpublic 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 initializationvoid 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 framevoid 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 initializationvoid 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 framevoid 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 initializationvoid 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 framevoid 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 initializationvoid Start () {}// Update is called once per framevoid 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 initializationvoid 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 framevoid 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 initializationvoid 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 framevoid 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 initializationvoid 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 framevoid 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 initializationvoid 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 framevoid 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 initializationvoid 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 framevoid Update () {}
}

转载于:https://www.cnblogs.com/1138720556Gary/p/9503342.html

Unity3D_(游戏)卡牌03_选关界面相关推荐

  1. Html5 Egret游戏开发 成语大挑战(四)选关界面

    Html5 Egret游戏开发 成语大挑战(四)选关界面 通过前面的开始界面基本上了解了eui的使用方法,可以简单快速的制作一个UI界面,本篇使用第二界面选关界面展示更为难一点的代码控制,来展现关卡地 ...

  2. Unity关于选关界面的制作

    选关界面,就像这样: 1.在Canvas中创建一个选关界面,同时添加Grid Layout Group组件: 通过调节组件中的属性可以管理子物体的大小与间距(这里指关卡按钮) 创建关卡按钮在Conte ...

  3. Python批量爬取游戏卡牌信息

    文章目录 前言 一.需求 二.分析 三.处理 四.运行结果 前言 本系列文章来源于真实的需求 本系列文章你来提我来做 本系列文章仅供学习参考 阅读人群:有Python基础.Scrapy框架基础 一.需 ...

  4. 游戏卡牌半小时拍出8700万天价,法院紧急叫停!

    6月21日,一张<游戏王>的纪念卡牌"青眼白龙"司法拍卖于阿里拍卖上正式开始.然而,距拍卖开始仅半个小时,这张卡牌便.拍出了约8732.61万元的"天价&qu ...

  5. Unity中游戏卡牌滚动效果,EnhanceScrollview(适用于NGUI,UGUI)

    最近项目中的活动面板要做来回滚动卡牌预览效果,感觉自己来写的话,也能写,但是可能会比较耗时,看到Github上有开源的项目,于是就借用了,Github的资源地址是:https://github.com ...

  6. C++小游戏——卡牌加减乘

    #include <iostream> #include <algorithm> #include <cstdlib> #include <ctime> ...

  7. [Unity游戏]卡牌记忆消除游戏

    1. 效果和工程 先来看看游戏是什么样子的,以下是在编辑器中运行的效果 完整的工程 https://github.com/MangoWAY/Unity2DMemoryCard,可以给个Star哈 2. ...

  8. 游戏卡牌UI设计教程

    来源:uimaker.com

  9. SPS | 卡牌游戏Splinterlands,你也可以达到最强王者

    那些最好的买卖,刚开始的时候,从数字上看,几乎都会告诉你不要买.--沃伦·巴菲特 现在的链游,概念预售为多,真正能玩的少.不少项目,游戏还没做出来,就开始炒预期,或者收一笔不少的入场费. 我今天想跟大 ...

最新文章

  1. 实用目标检测器 | 性能超YoloV5,推理耗时不变(附github源码)
  2. 《幸福资本论》读书笔记
  3. IOS中获取各个文件的目录路径的方法和NSFileManager类
  4. unity调用 Android 分享图片文字 方法 不需要第三方sdk 兼容android7.0+
  5. typescript tslint rules config
  6. php点击按钮显示隐藏代码,jQuery中点击按钮实现显示与隐藏的方法
  7. 我30岁了。现在开始编程,会不会太晚?
  8. 查询php的扩展,php命令行查看扩展信息(示例代码)
  9. 518. 零钱兑换 II(JavaScript)
  10. 蓝牙 MultipeerConnectivity
  11. 从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的(网易)。...
  12. nodepad++通过正则表达式,删除带有特殊字符的某一行
  13. H264视频解码器C++工程说明
  14. 分布式定时任务调度框架
  15. Excel里怎么设置输入可以打钩的选择框?
  16. 2021-2027全球与中国铂金芯片温度传感器市场现状及未来发展趋势
  17. 2018国内VR游戏现状
  18. 计算机键盘标注,电脑键盘上怎么打√和×
  19. 国外游戏开发公司10强
  20. 黑龙江省大庆市谷歌高清卫星地图下载

热门文章

  1. IIS和Asp.Net页面运行机制
  2. 项目经理的软技能提升——知行合一
  3. 【重识 HTML + CSS】网页基础知识、基本 HTML 标签
  4. Linux下安装 卸载mysql57 msyql80
  5. 为什么火车上的网速都超级慢,并且信号极差?
  6. python列表解析,生成表达式(一分钟读懂)
  7. java 线程 listview_android使用Thread实现json数据的传递,并且使用ListView显示
  8. javascript 中文帮助文档_我的《ANSA快速入门指南》中文帮助文档浅析(上)
  9. 计算机网络 第五章 运输层
  10. 01背包问题-一维数组实现原理