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

卡牌01_启动屏界面  传送门

卡牌02_主菜单界面  传送门

卡牌03_选关界面   传送门

卡牌04_游戏界面     传送门

选关界面效果

  (鼠标放在不同关卡上显示不同的关卡提示信息点击关卡按钮时候出现短暂粉红色点击效果点击返回主菜单游戏回到主菜单界面点击游戏关卡进入游戏界面)

  

  不同游戏主题显示不同数量的关卡,用到了游戏数据管理类,不同游戏主题显示的卡牌不同

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class DataMgr {
  6. private static DataMgr ins = null;
  7.  
  8. public THEME_ID themeId;
  9.  
  10. //某一主题所有关卡数据
  11. public LevelData levelData;
  12. public int levelId; //进入游戏前,保存当前选择的关卡id
  13. public LevelInfo levelInfo; //当前关卡信息
  14.  
  15. private DataMgr()
  16. {
  17. //将构造函数设置为私有,这样避免外部创建类的实例,只能通过Instance()来获取数据管理类的实例
  18. }
  19.  
  20. public static DataMgr Instance()
  21. {
  22. if(ins == null)
  23. {
  24. ins = new DataMgr();
  25. }
  26. return ins;
  27. }
  28.  
  29. public LevelData InitLevelData(THEME_ID id)
  30. {
  31. levelData = null;
  32. switch (id)
  33. {
  34. case THEME_ID.Logo:
  35. levelData = Resources.Load<LevelData>("Prefabs/data/LevelDataLogo");
  36. break;
  37. case THEME_ID.Student:
  38. levelData = Resources.Load<LevelData>("Prefabs/data/LevelDataStudent");
  39. break;
  40. default:
  41. levelData = Resources.Load<LevelData>("Prefabs/data/LevelDataLogo");
  42. break;
  43. }
  44. return levelData;
  45. }
  46. }

DataMgr.class (数据管理类)

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.SceneManagement;
  5. using UnityEngine.UI;
  6.  
  7. public enum THEME_ID
  8. {
  9. Logo,
  10. Student
  11. }
  12.  
  13. public class Scene_MainMenu : MonoBehaviour {
  14.  
  15. // Use this for initialization
  16. void Start () {
  17. GameObject.Find("LogoBtn").GetComponent<Button>().onClick.AddListener(()=>{ OnClickThemeBtn(THEME_ID.Logo); });
  18. GameObject.Find("StudentBtn").GetComponent<Button>().onClick.AddListener(() => { OnClickThemeBtn(THEME_ID.Student); });
  19. GameObject.Find("CloseBtn").GetComponent<Button>().onClick.AddListener(() => { OnCloseApp(); });
  20. }
  21.  
  22. // Update is called once per frame
  23. void Update () {
  24.  
  25. }
  26.  
  27. void OnClickThemeBtn(THEME_ID theme)
  28. {
  29. SceneManager.LoadScene("SelectLevel");
  30. DataMgr.Instance().themeId = theme;
  31. }
  32.  
  33. //退出程序
  34. void OnCloseApp()
  35. {
  36. Application.Quit();
  37. }
  38.  
  39. }

Scene_MainMenu.cs (关卡场景脚本)

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using UnityEngine.EventSystems;
  6. using UnityEngine.SceneManagement;
  7.  
  8. //选关界面,每一个关卡按钮单元
  9. public class LevelItemCell : MonoBehaviour ,IPointerEnterHandler,IPointerExitHandler,
  10. IPointerDownHandler,IPointerUpHandler,IPointerClickHandler{
  11. public RectTransform numTrans;
  12. public GameObject LockObj;
  13. public GameObject pressObj;
  14.  
  15. //[HideInInspector]
  16.  
  17. public int id; //每个单元对应的关卡id(从1开始)
  18. public LevelManager lvlMgr;
  19.  
  20. LevelInfo levelInfo;
  21.  
  22. //点击按钮,跳转到游戏界面
  23. public void OnPointerClick(PointerEventData eventData)
  24. {
  25. DataMgr.Instance().levelId = id;
  26. DataMgr.Instance().levelInfo = levelInfo;
  27. SceneManager.LoadScene("Gameplay");
  28. }
  29.  
  30. public void OnPointerDown(PointerEventData eventData)
  31. {
  32. pressObj.SetActive(true);
  33. }
  34.  
  35. //当鼠标进入本单元矩形区域,显示当前关卡描述
  36. public void OnPointerEnter(PointerEventData eventData)
  37. {
  38. lvlMgr.SetLevelDesc(levelInfo.desc);
  39.  
  40. }
  41.  
  42. public void OnPointerExit(PointerEventData eventData)
  43. {
  44. lvlMgr.SetLevelDesc("关卡信息");
  45. }
  46.  
  47. public void OnPointerUp(PointerEventData eventData)
  48. {
  49. pressObj.SetActive(false);
  50. }
  51.  
  52. private void Awake()
  53. {
  54. LockObj.SetActive(false);
  55. pressObj.SetActive(false);
  56. }
  57.  
  58. // Use this for initialization
  59. void Start () {
  60. float scale = ;
  61. //初始化关卡数字显示
  62. if (id < )
  63. {
  64. //完全用代码动态创建一个Image对象,并作为num的子节点
  65. GameObject obj = new GameObject("num1",typeof(Image));
  66. RectTransform rtf = obj.GetComponent<RectTransform>();
  67. rtf.SetParent(numTrans);
  68. //设置数字
  69. Image img = obj.GetComponent<Image>();
  70. img.sprite = lvlMgr.spr_nums[id];
  71. img.SetNativeSize(); //图片原始尺寸
  72. rtf.localScale = new Vector3(,,);
  73. rtf.localPosition = Vector3.zero;
  74.  
  75. }
  76. else if (id<)
  77. {
  78. //十位数
  79. GameObject obj = new GameObject("num1", typeof(Image));
  80. RectTransform rtf = obj.GetComponent<RectTransform>();
  81. rtf.SetParent(numTrans);
  82. //设置数字
  83. Image img = obj.GetComponent<Image>();
  84. img.sprite = lvlMgr.spr_nums[id/];
  85. img.SetNativeSize(); //图片原始尺寸
  86. rtf.localScale = new Vector3(, , );
  87. rtf.localPosition = new Vector3(-scale * rtf.rect.width/-,,);
  88.  
  89. //个位数
  90. GameObject obj2 = new GameObject("num2", typeof(Image));
  91. RectTransform rtf2 = obj2.GetComponent<RectTransform>();
  92. rtf2.SetParent(numTrans);
  93. //设置数字
  94. Image img2 = obj2.GetComponent<Image>();
  95. img2.sprite = lvlMgr.spr_nums[id % ];
  96. img2.SetNativeSize(); //图片原始尺寸
  97. rtf2.localScale = new Vector3(, , );
  98. rtf2.localPosition = new Vector3(scale * rtf2.rect.width / + , , );
  99. }
  100. levelInfo = DataMgr.Instance().levelData.levels[id - ];
  101. }
  102.  
  103. // Update is called once per frame
  104. void Update () {
  105.  
  106. }
  107. }

LevelItemCell.cs (每一个关卡按钮单元脚本)

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using DG.Tweening;
  6. using UnityEngine.SceneManagement;
  7.  
  8. //用来管理所有关卡按钮
  9. //根据我们关卡数据定义,判断一共多少个关卡按钮。LevelManager来创建LevelPanelCell表格单元,LevelPanelCell表格单元是LevelItemCell
  10. public class LevelManager : MonoBehaviour
  11. {
  12.  
  13. int totalCount = ; //临时测试,一共18关
  14. readonly int ITEM_COUNT_PAGE = ; //每一页显示15个关卡
  15. readonly float PANEL_SPACE = 10f;
  16. readonly float MOVE_TIME = 0.5f;
  17.  
  18. public RectTransform contenTrans;
  19. public Sprite[] spr_nums;
  20.  
  21. float panelCellOffset;
  22. int pageCount;
  23.  
  24. GameObject levelPanelCellPreb;
  25. GameObject levelItemCellPreb;
  26. Text levelDescTxt;
  27.  
  28. float pointerDownTimeBak;
  29. float pointerDownX;
  30.  
  31. int pageIdx;
  32.  
  33. public void Awake()
  34. {
  35. levelPanelCellPreb = Resources.Load<GameObject>("Prefabs/SelectLevel/LevelPanelCell");
  36. levelItemCellPreb = Resources.Load("Prefabs/SelectLevel/LevelItemCell") as GameObject;
  37. levelDescTxt = GameObject.Find("LevelDesc/text").GetComponent<Text>();
  38.  
  39. GameObject.Find("BackMainMenu").GetComponent<Button>().onClick.AddListener(()=> { OnBackMainMenuBtn(); });
  40.  
  41. DataMgr.Instance().InitLevelData(DataMgr.Instance().themeId);
  42. totalCount = DataMgr.Instance().levelData.levels.Length; //根据关卡数据表的个数,动态设置单元数量
  43. }
  44.  
  45. // Use this for initialization
  46. void Start()
  47. {
  48. //计算panel的偏移
  49. panelCellOffset = contenTrans.rect.width + PANEL_SPACE;
  50. //计算出一共需要多少页
  51. pageCount = Mathf.CeilToInt((float)totalCount / ITEM_COUNT_PAGE);
  52. //当前显示的第几页表格panel,从0开始
  53. pageIdx = ;
  54.  
  55. for (int i = ; i < pageCount; i++)
  56. {
  57. CreateLevelPanclCell(i);
  58. }
  59. }
  60.  
  61. // Update is called once per frame
  62. void Update()
  63. {
  64. //按下时记录鼠标当前位置
  65. if (Input.GetMouseButtonDown())
  66. {
  67. pointerDownTimeBak = Time.time;
  68. pointerDownX = Input.mousePosition.x;
  69. }
  70.  
  71. if (Input.GetMouseButtonUp())
  72. {
  73. //模拟滑动事件,假定很短时间的滑动
  74. if (Time.time - pointerDownTimeBak < 0.5f)
  75. {
  76. float offsetX = Input.mousePosition.x - pointerDownX;
  77. //向左滑动鼠标,并超过一定距离
  78. if (offsetX < - && pageIdx < pageCount - )
  79. {
  80. //向左滑动鼠标,并超过一段距离
  81. pageIdx++;
  82. //执行所有表格面板向左平滑滑动
  83. //0.5秒对自身左边叠加量,向左移动一段距离
  84. contenTrans.DOBlendableLocalMoveBy(new Vector3(-panelCellOffset, , ), MOVE_TIME);
  85.  
  86. }
  87. else if (offsetX > && pageIdx > )
  88. {
  89. //向右滑动鼠标,并超过一段距离
  90. pageIdx--;
  91. //执行所有表格面板向右平滑滑动
  92. //0.5秒对自身左边叠加量,向右移动一段距离
  93. contenTrans.DOBlendableLocalMoveBy(new Vector3(panelCellOffset, , ), MOVE_TIME);
  94. }
  95. }
  96. }
  97. }
  98.  
  99. //创建表格panel,从0开始编号
  100. void CreateLevelPanclCell(int pageInx)
  101. {
  102. GameObject panelObj = Instantiate(levelPanelCellPreb, contenTrans);
  103. RectTransform panelTrans = panelObj.GetComponent<RectTransform>();
  104. panelTrans.anchoredPosition = new Vector2(panelCellOffset * pageInx, );
  105.  
  106. //确定本业 中具有的关卡元素个数
  107. int startId = ITEM_COUNT_PAGE * pageInx;
  108. //本业需要显示按钮的个数
  109. int count = totalCount - startId;
  110.  
  111. if (count > ITEM_COUNT_PAGE)
  112. {
  113. count = ITEM_COUNT_PAGE;
  114. }
  115.  
  116. //创建本页中所有关卡按钮
  117. for (int i = ; i < count; i++)
  118. {
  119. //创建每一个关卡的按钮单元
  120. GameObject itemObj = Instantiate(levelItemCellPreb, panelTrans);
  121.  
  122. //这一段cell相关调用,实在Start()之前执行的
  123. LevelItemCell cell = itemObj.GetComponent<LevelItemCell>();
  124. cell.id = startId + i + ; //设置每个单元的关卡编号
  125. cell.lvlMgr = this;
  126. itemObj.name = cell.id.ToString();
  127.  
  128. }
  129.  
  130. }
  131.  
  132. //设置关卡描述
  133. public void SetLevelDesc(string content)
  134. {
  135. levelDescTxt.text = content;
  136. }
  137.  
  138. void OnBackMainMenuBtn()
  139. {
  140. SceneManager.LoadScene("MainMenu");
  141. }
  142. }

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关卡页面范围上

  1. public RectTransform contenTrans;

  计算panel的偏移

  1. readonly float PANEL_SPACE = 10f;
  2.  
  3. panelCellffset = contenTrans.rect.width + PANEL_SPACE;

  计算出一共需要多少页

  1. int totalCount = ; //临时测试,一共18关
  2. readonly int ITEM_COUNT_PAGE = ; //每一页显示15个关卡
  3. readonly float PANEL_SPACE = 10f;
  4.  
  5. pageCount = Mathf.CeilToInt((float)totalCount / ITEM_COUNT_PAGE);

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

  

  获得游戏控件UI

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

  创建表格panel,从0开始编号

  1. void CreateLevelPanclCell(int pageInx)
  2. {
  3. GameObject panelObj = Instantiate(levelPanelCellPreb,contenTrans);
  4. RectTransform panelTrans = panelObj.GetComponent<RectTransform>();
  5. panelTrans.anchoredPosition = new Vector2(panelCellOffset * pageInx, );
  6.  
  7. //确定本业 中具有的关卡元素个数
  8. int startId = ITEM_COUNT_PAGE * pageInx;
  9. //本业需要显示按钮的个数
  10. int count = totalCount - startId;
  11.  
  12. if (count > ITEM_COUNT_PAGE)
  13. {
  14. count = ITEM_COUNT_PAGE;
  15. }
  16.  
  17. //创建本页中所有关卡按钮
  18. for(int i =;i<count;i++)
  19. {
  20. //创建每一个关卡的按钮单元
  21. GameObject itemObj = Instantiate(levelItemCellPreb,panelTrans);
  22.  
  23. LevelItemCell cell = itemObj.GetComponent<LevelItemCell>();
  24. cell.id = startId+i+;
  25. cell.lvlMgr = this;
  26. itemObj.name = cell.id.ToString();
  27.  
  28. }
  29.  
  30. }

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. //选关界面,每一个关卡按钮单元
  6. public class LevelItemCell : MonoBehaviour {
  7.  
  8. public int id; //每个单元对应的关卡id(从1开始)
  9. public LevelManager lvlMgr;
  10.  
  11. // Use this for initialization
  12. void Start () {
  13.  
  14. }
  15.  
  16. // Update is called once per frame
  17. void Update () {
  18.  
  19. }
  20. }

LevelItemCell.cs

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5.  
  6. //用来管理所有关卡按钮
  7. //根据我们关卡数据定义,判断一共多少个关卡按钮。LevelManager来创建LevelPanelCell表格单元,LevelPanelCell表格单元是LevelItemCell
  8. public class LevelManager : MonoBehaviour {
  9.  
  10. int totalCount = ; //临时测试,一共18关
  11. readonly int ITEM_COUNT_PAGE = ; //每一页显示15个关卡
  12. readonly float PANEL_SPACE = 10f;
  13.  
  14. public RectTransform contenTrans;
  15. float panelCellOffset;
  16. int pageCount;
  17.  
  18. GameObject levelPanelCellPreb;
  19. GameObject levelItemCellPreb;
  20. Text levelDescTxt;
  21.  
  22. //int pageIdx;
  23.  
  24. public void Awake()
  25. {
  26. levelPanelCellPreb = Resources.Load<GameObject>("Prefabs/SelectLevel/LevelPanelCell");
  27. levelItemCellPreb = Resources.Load("Prefabs/SelectLevel/LevelItemCell") as GameObject;
  28. levelDescTxt = GameObject.Find("LevelDesc/text").GetComponent<Text>();
  29.  
  30. }
  31.  
  32. // Use this for initialization
  33. void Start () {
  34. //计算panel的偏移
  35. panelCellOffset = contenTrans.rect.width + PANEL_SPACE;
  36. //计算出一共需要多少页
  37. pageCount = Mathf.CeilToInt((float)totalCount / ITEM_COUNT_PAGE);
  38.  
  39. // pageIdx = 0;
  40. for (int i = ; i < pageCount; i++)
  41. {
  42. CreateLevelPanclCell(i);
  43. }
  44. }
  45.  
  46. // Update is called once per frame
  47. void Update () {
  48.  
  49. }
  50.  
  51. //创建表格panel,从0开始编号
  52. void CreateLevelPanclCell(int pageInx)
  53. {
  54. GameObject panelObj = Instantiate(levelPanelCellPreb,contenTrans);
  55. RectTransform panelTrans = panelObj.GetComponent<RectTransform>();
  56. panelTrans.anchoredPosition = new Vector2(panelCellOffset * pageInx, );
  57.  
  58. //确定本业 中具有的关卡元素个数
  59. int startId = ITEM_COUNT_PAGE * pageInx;
  60. //本业需要显示按钮的个数
  61. int count = totalCount - startId;
  62.  
  63. if (count > ITEM_COUNT_PAGE)
  64. {
  65. count = ITEM_COUNT_PAGE;
  66. }
  67.  
  68. //创建本页中所有关卡按钮
  69. for(int i =;i<count;i++)
  70. {
  71. //创建每一个关卡的按钮单元
  72. GameObject itemObj = Instantiate(levelItemCellPreb,panelTrans);
  73.  
  74. LevelItemCell cell = itemObj.GetComponent<LevelItemCell>();
  75. cell.id = startId+i+;
  76. cell.lvlMgr = this;
  77. itemObj.name = cell.id.ToString();
  78.  
  79. }
  80.  
  81. }
  82.  
  83. //设置关卡描述
  84. void SetLevelDesc(string content)
  85. {
  86. levelDescTxt.text = content;
  87. }
  88. }

LevelManager.cs

  因为我们默认初始化游戏18个关卡,一个选关界面存放15个关卡

  所有关卡时出现出现两个选关界面

  为了只出现一个选关界面

  使用Unity提供的Mask插件

  Mask插件:提供给需要Mask的图片修改渲染顶点,达到遮罩效果

  在LevelManager控件上添加Mask插件

整体滑动效果

  DOTween插件控制选关界面移动  下载:传送门

  下载完后,把解压的包,直接拖入工程 在unity 菜单栏 Tools—Demigiant—DOTween Utility Panel。点击后,在右图中点击Setup DOTween… 工具会导入必要的库。

滑动效果效果:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using DG.Tweening;
  6.  
  7. //用来管理所有关卡按钮
  8. //根据我们关卡数据定义,判断一共多少个关卡按钮。LevelManager来创建LevelPanelCell表格单元,LevelPanelCell表格单元是LevelItemCell
  9. public class LevelManager : MonoBehaviour {
  10.  
  11. int totalCount = ; //临时测试,一共18关
  12. readonly int ITEM_COUNT_PAGE = ; //每一页显示15个关卡
  13. readonly float PANEL_SPACE = 10f;
  14. readonly float MOVE_TIME = 0.5f;
  15.  
  16. public RectTransform contenTrans;
  17. float panelCellOffset;
  18. int pageCount;
  19.  
  20. GameObject levelPanelCellPreb;
  21. GameObject levelItemCellPreb;
  22. Text levelDescTxt;
  23.  
  24. float pointerDownTimeBak;
  25. float pointerDownX;
  26.  
  27. int pageIdx;
  28.  
  29. public void Awake()
  30. {
  31. levelPanelCellPreb = Resources.Load<GameObject>("Prefabs/SelectLevel/LevelPanelCell");
  32. levelItemCellPreb = Resources.Load("Prefabs/SelectLevel/LevelItemCell") as GameObject;
  33. levelDescTxt = GameObject.Find("LevelDesc/text").GetComponent<Text>();
  34. }
  35.  
  36. // Use this for initialization
  37. void Start () {
  38. //计算panel的偏移
  39. panelCellOffset = contenTrans.rect.width + PANEL_SPACE;
  40. //计算出一共需要多少页
  41. pageCount = Mathf.CeilToInt((float)totalCount / ITEM_COUNT_PAGE);
  42. //当前显示的第几页表格panel,从0开始
  43. pageIdx = ;
  44.  
  45. for (int i = ; i < pageCount; i++)
  46. {
  47. CreateLevelPanclCell(i);
  48. }
  49. }
  50.  
  51. // Update is called once per frame
  52. void Update () {
  53. //按下时记录鼠标当前位置
  54. if (Input.GetMouseButtonDown())
  55. {
  56. pointerDownTimeBak = Time.time;
  57. pointerDownX = Input.mousePosition.x;
  58. }
  59.  
  60. if(Input.GetMouseButtonUp())
  61. {
  62. //模拟滑动事件,假定很短时间的滑动
  63. if(Time.time - pointerDownTimeBak<0.5f)
  64. {
  65. float offsetX = Input.mousePosition.x - pointerDownX;
  66. //向左滑动鼠标,并超过一定距离
  67. if (offsetX < - && pageIdx<pageCount-)
  68. {
  69. //向左滑动鼠标,并超过一段距离
  70. pageIdx++;
  71. //执行所有表格面板向左平滑滑动
  72. //0.5秒对自身左边叠加量,向左移动一段距离
  73. contenTrans.DOBlendableLocalMoveBy(new Vector3(-panelCellOffset, , ), MOVE_TIME);
  74.  
  75. }else if (offsetX>&&pageIdx>)
  76. {
  77. //向右滑动鼠标,并超过一段距离
  78. pageIdx--;
  79. //执行所有表格面板向右平滑滑动
  80. //0.5秒对自身左边叠加量,向右移动一段距离
  81. contenTrans.DOBlendableLocalMoveBy(new Vector3(panelCellOffset, , ), MOVE_TIME);
  82. }
  83. }
  84. }
  85. }
  86.  
  87. //创建表格panel,从0开始编号
  88. void CreateLevelPanclCell(int pageInx)
  89. {
  90. GameObject panelObj = Instantiate(levelPanelCellPreb,contenTrans);
  91. RectTransform panelTrans = panelObj.GetComponent<RectTransform>();
  92. panelTrans.anchoredPosition = new Vector2(panelCellOffset * pageInx, );
  93.  
  94. //确定本业 中具有的关卡元素个数
  95. int startId = ITEM_COUNT_PAGE * pageInx;
  96. //本业需要显示按钮的个数
  97. int count = totalCount - startId;
  98.  
  99. if (count > ITEM_COUNT_PAGE)
  100. {
  101. count = ITEM_COUNT_PAGE;
  102. }
  103.  
  104. //创建本页中所有关卡按钮
  105. for(int i =;i<count;i++)
  106. {
  107. //创建每一个关卡的按钮单元
  108. GameObject itemObj = Instantiate(levelItemCellPreb,panelTrans);
  109.  
  110. LevelItemCell cell = itemObj.GetComponent<LevelItemCell>();
  111. cell.id = startId+i+;
  112. cell.lvlMgr = this;
  113. itemObj.name = cell.id.ToString();
  114.  
  115. }
  116.  
  117. }
  118.  
  119. //设置关卡描述
  120. void SetLevelDesc(string content)
  121. {
  122. levelDescTxt.text = content;
  123. }
  124. }

LevelManager.cs

  MOVE_TIME时间内选择关卡向左边的叠加量,向左移动一段距离

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

  按下时记录鼠标当前位置

  1. if (Input.GetMouseButtonDown())
  2. {
  3. pointerDownTimeBak = Time.time;
  4. pointerDownX = Input.mousePosition.x;
  5. }

  松开鼠标时触发事件

  1. if(Input.GetMouseButtonUp())
  2. {
  3. //模拟滑动事件,假定很短时间的滑动
  4. if(Time.time - pointerDownTimeBak<0.5f)
  5. {
  6. float offsetX = Input.mousePosition.x - pointerDownX;
  7. //向左滑动鼠标,并超过一定距离
  8. if (offsetX < - && pageIdx<pageCount-)
  9. {
  10. //向左滑动鼠标,并超过一段距离
  11. pageIdx++;
  12. //执行所有表格面板向左平滑滑动
  13. //0.5秒对自身左边叠加量,向左移动一段距离
  14. contenTrans.DOBlendableLocalMoveBy(new Vector3(-panelCellOffset, , ), MOVE_TIME);
  15.  
  16. }else if (offsetX>&&pageIdx>)
  17. {
  18. //向右滑动鼠标,并超过一段距离
  19. pageIdx--;
  20. //执行所有表格面板向右平滑滑动
  21. //0.5秒对自身左边叠加量,向右移动一段距离
  22. contenTrans.DOBlendableLocalMoveBy(new Vector3(panelCellOffset, , ), MOVE_TIME);
  23. }
  24. }
  25. }

代码创建关卡数字

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5.  
  6. //选关界面,每一个关卡按钮单元
  7. public class LevelItemCell : MonoBehaviour {
  8. public RectTransform numTrans;
  9. public int id; //每个单元对应的关卡id(从1开始)
  10. public LevelManager lvlMgr;
  11.  
  12. private void Awake()
  13. {
  14.  
  15. }
  16.  
  17. // Use this for initialization
  18. void Start () {
  19. float scale = ;
  20. //初始化关卡数字显示
  21. if (id < )
  22. {
  23. //完全用代码动态创建一个Image对象,并作为num的子节点
  24. GameObject obj = new GameObject("num1",typeof(Image));
  25. RectTransform rtf = obj.GetComponent<RectTransform>();
  26. rtf.SetParent(numTrans);
  27. //设置数字
  28. Image img = obj.GetComponent<Image>();
  29. img.sprite = lvlMgr.spr_nums[id];
  30. img.SetNativeSize(); //图片原始尺寸
  31. rtf.localScale = new Vector3(,,);
  32. rtf.localPosition = Vector3.zero;
  33.  
  34. }
  35. else if (id<)
  36. {
  37. //十位数
  38. GameObject obj = new GameObject("num1", typeof(Image));
  39. RectTransform rtf = obj.GetComponent<RectTransform>();
  40. rtf.SetParent(numTrans);
  41. //设置数字
  42. Image img = obj.GetComponent<Image>();
  43. img.sprite = lvlMgr.spr_nums[id/];
  44. img.SetNativeSize(); //图片原始尺寸
  45. rtf.localScale = new Vector3(, , );
  46. rtf.localPosition = new Vector3(-scale * rtf.rect.width/-,,);
  47.  
  48. //个位数
  49. GameObject obj2 = new GameObject("num2", typeof(Image));
  50. RectTransform rtf2 = obj2.GetComponent<RectTransform>();
  51. rtf2.SetParent(numTrans);
  52. //设置数字
  53. Image img2 = obj2.GetComponent<Image>();
  54. img2.sprite = lvlMgr.spr_nums[id % ];
  55. img2.SetNativeSize(); //图片原始尺寸
  56. rtf2.localScale = new Vector3(, , );
  57. rtf2.localPosition = new Vector3(scale * rtf2.rect.width / + , , );
  58. }
  59. }
  60.  
  61. // Update is called once per frame
  62. void Update () {
  63.  
  64. }
  65. }

LevelItemCell.cs

  num子节点下创建两个Image控件存放数字

  定义Sprite[]数组,将图片绑定上去

  1. public Sprite[] spr_nums;

  用代码动态创建一个Image对象,并作为num的子节点

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

  图片原始尺寸

  1. img.SetNativeSize();

  图片的缩放比例

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

  当id<10时,定义图片放置的位置

  1. rtf.localPosition = Vector3.zero;
  1. if (id < )
  2. {
  3. //完全用代码动态创建一个Image对象,并作为num的子节点
  4. GameObject obj = new GameObject("num1",typeof(Image));
  5. RectTransform rtf = obj.GetComponent<RectTransform>();
  6. rtf.SetParent(numTrans);
  7. //设置数字
  8. Image img = obj.GetComponent<Image>();
  9. img.sprite = lvlMgr.spr_nums[id];
  10. img.SetNativeSize(); //图片原始尺寸
  11. rtf.localScale = new Vector3(,,);
  12. rtf.localPosition = Vector3.zero;
  13.  
  14. }

  个位数位置

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

  十位数位置

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

  同理个位数,不同在于图片摆放的位置

  1. else if (id<)
  2. {
  3. //十位数
  4. GameObject obj = new GameObject("num1", typeof(Image));
  5. RectTransform rtf = obj.GetComponent<RectTransform>();
  6. rtf.SetParent(numTrans);
  7. //设置数字
  8. Image img = obj.GetComponent<Image>();
  9. img.sprite = lvlMgr.spr_nums[id/];
  10. img.SetNativeSize(); //图片原始尺寸
  11. rtf.localScale = new Vector3(, , );
  12. rtf.localPosition = new Vector3(-scale * rtf.rect.width/-,,);
  13.  
  14. //个位数
  15. GameObject obj2 = new GameObject("num2", typeof(Image));
  16. RectTransform rtf2 = obj2.GetComponent<RectTransform>();
  17. rtf2.SetParent(numTrans);
  18. //设置数字
  19. Image img2 = obj2.GetComponent<Image>();
  20. img2.sprite = lvlMgr.spr_nums[id % ];
  21. img2.SetNativeSize(); //图片原始尺寸
  22. rtf2.localScale = new Vector3(, , );
  23. rtf2.localPosition = new Vector3(scale * rtf2.rect.width / + , , );
  24. }

数据管理类

  1. unity除非特别指定,当切换到新场景时原场景中所有游戏对象都会销毁。那么伴随着挂在对象上的脚本也会销毁。
  2. 我们需要有一个类,能够使各处都能够便利访问。并且这个类对象实例,只需要一个

Unity_单例模式

  第一个游戏主题只有18关

  第一个游戏主题有20关

  ( Unity引擎加载场景有点慢(´・_・`)  )

  某一主题所有关卡数据

  1. public LevelData levelData;

  点击不同主题按钮选择不同主题的关卡

  1. void OnClickThemeBtn(THEME_ID theme)
  2. {
  3. SceneManager.LoadScene("SelectLevel");
  4. DataMgr.Instance().themeId = theme;
  5. }
  1. public LevelData InitLevelData(THEME_ID id)
  2. {
  3. levelData = null;
  4. switch (id)
  5. {
  6. case THEME_ID.Logo:
  7. levelData = Resources.Load<LevelData>("Prefabs/data/LevelDataLogo");
  8. break;
  9. case THEME_ID.Student:
  10. levelData = Resources.Load<LevelData>("Prefabs/data/LevelDataStudent");
  11. break;
  12. default:
  13. levelData = Resources.Load<LevelData>("Prefabs/data/LevelDataLogo");
  14. break;
  15. }
  16. return levelData;
  17. }

关卡单元实现

  添加两个游戏主键的引用

  1. public GameObject LockObj;
  2. public GameObject pressObj;

  点击按钮时关卡单元变色Image和锁的Image添加上去

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using UnityEngine.EventSystems;
  6. using UnityEngine.SceneManagement;
  7.  
  8. //选关界面,每一个关卡按钮单元
  9. public class LevelItemCell : MonoBehaviour ,IPointerEnterHandler,IPointerExitHandler,
  10. IPointerDownHandler,IPointerUpHandler,IPointerClickHandler{
  11. public RectTransform numTrans;
  12. public GameObject LockObj;
  13. public GameObject pressObj;
  14.  
  15. //[HideInInspector]
  16.  
  17. public int id; //每个单元对应的关卡id(从1开始)
  18. public LevelManager lvlMgr;
  19.  
  20. LevelInfo levelInfo;
  21.  
  22. //点击按钮,跳转到游戏界面
  23. public void OnPointerClick(PointerEventData eventData)
  24. {
  25. DataMgr.Instance().levelId = id;
  26. DataMgr.Instance().levelInfo = levelInfo;
  27. SceneManager.LoadScene("Gameplay");
  28. }
  29.  
  30. public void OnPointerDown(PointerEventData eventData)
  31. {
  32. pressObj.SetActive(true);
  33. }
  34.  
  35. //当鼠标进入本单元矩形区域,显示当前关卡描述
  36. public void OnPointerEnter(PointerEventData eventData)
  37. {
  38. lvlMgr.SetLevelDesc(levelInfo.desc);
  39.  
  40. }
  41.  
  42. public void OnPointerExit(PointerEventData eventData)
  43. {
  44. lvlMgr.SetLevelDesc("关卡信息");
  45. }
  46.  
  47. public void OnPointerUp(PointerEventData eventData)
  48. {
  49. pressObj.SetActive(false);
  50. }
  51.  
  52. private void Awake()
  53. {
  54. LockObj.SetActive(false);
  55. pressObj.SetActive(false);
  56. }
  57.  
  58. // Use this for initialization
  59. void Start () {
  60. float scale = ;
  61. //初始化关卡数字显示
  62. if (id < )
  63. {
  64. //完全用代码动态创建一个Image对象,并作为num的子节点
  65. GameObject obj = new GameObject("num1",typeof(Image));
  66. RectTransform rtf = obj.GetComponent<RectTransform>();
  67. rtf.SetParent(numTrans);
  68. //设置数字
  69. Image img = obj.GetComponent<Image>();
  70. img.sprite = lvlMgr.spr_nums[id];
  71. img.SetNativeSize(); //图片原始尺寸
  72. rtf.localScale = new Vector3(,,);
  73. rtf.localPosition = Vector3.zero;
  74.  
  75. }
  76. else if (id<)
  77. {
  78. //十位数
  79. GameObject obj = new GameObject("num1", typeof(Image));
  80. RectTransform rtf = obj.GetComponent<RectTransform>();
  81. rtf.SetParent(numTrans);
  82. //设置数字
  83. Image img = obj.GetComponent<Image>();
  84. img.sprite = lvlMgr.spr_nums[id/];
  85. img.SetNativeSize(); //图片原始尺寸
  86. rtf.localScale = new Vector3(, , );
  87. rtf.localPosition = new Vector3(-scale * rtf.rect.width/-,,);
  88.  
  89. //个位数
  90. GameObject obj2 = new GameObject("num2", typeof(Image));
  91. RectTransform rtf2 = obj2.GetComponent<RectTransform>();
  92. rtf2.SetParent(numTrans);
  93. //设置数字
  94. Image img2 = obj2.GetComponent<Image>();
  95. img2.sprite = lvlMgr.spr_nums[id % ];
  96. img2.SetNativeSize(); //图片原始尺寸
  97. rtf2.localScale = new Vector3(, , );
  98. rtf2.localPosition = new Vector3(scale * rtf2.rect.width / + , , );
  99. }
  100. levelInfo = DataMgr.Instance().levelData.levels[id - ];
  101. }
  102.  
  103. // Update is called once per frame
  104. void Update () {
  105.  
  106. }
  107. }

LevelItemCell.cs

  初始化时点击单元关卡(粉红色效果)和锁(效果)不可见

  1. private void Awake()
  2. {
  3. LockObj.SetActive(false);
  4. pressObj.SetActive(false);
  5. }

  点击按钮事件

  1. //点击按钮,跳转到游戏界面
  2. public void OnPointerClick(PointerEventData eventData)
  3. {
  4. DataMgr.Instance().levelId = id;
  5. DataMgr.Instance().levelInfo = levelInfo;
  6. SceneManager.LoadScene("Gameplay");
  7. }
  8.  
  9. public void OnPointerDown(PointerEventData eventData)
  10. {
  11. pressObj.SetActive(true);
  12. }
  13.  
  14. //当鼠标进入本单元矩形区域,显示当前关卡描述
  15. public void OnPointerEnter(PointerEventData eventData)
  16. {
  17. lvlMgr.SetLevelDesc(levelInfo.desc);
  18.  
  19. }
  20.  
  21. public void OnPointerExit(PointerEventData eventData)
  22. {
  23. lvlMgr.SetLevelDesc("关卡信息");
  24. }
  25.  
  26. public void OnPointerUp(PointerEventData eventData)
  27. {
  28. pressObj.SetActive(false);
  29. }
  1. public class LevelItemCell : MonoBehaviour ,IPointerEnterHandler,IPointerExitHandler,
  2. IPointerDownHandler,IPointerUpHandler,IPointerClickHandler{
  3. public RectTransform numTrans;
  4. public GameObject LockObj;
  5. public GameObject pressObj;
  6.  
  7. //[HideInInspector]
  8.  
  9. public int id; //每个单元对应的关卡id(从1开始)
  10. public LevelManager lvlMgr;
  11.  
  12. LevelInfo levelInfo;
  13.  
  14. //点击按钮,跳转到游戏界面
  15. public void OnPointerClick(PointerEventData eventData)
  16. {
  17. DataMgr.Instance().levelId = id;
  18. DataMgr.Instance().levelInfo = levelInfo;
  19. SceneManager.LoadScene("Gameplay");
  20. }
  21.  
  22. public void OnPointerDown(PointerEventData eventData)
  23. {
  24. pressObj.SetActive(true);
  25. }
  26.  
  27. //当鼠标进入本单元矩形区域,显示当前关卡描述
  28. public void OnPointerEnter(PointerEventData eventData)
  29. {
  30. lvlMgr.SetLevelDesc(levelInfo.desc);
  31.  
  32. }
  33.  
  34. public void OnPointerExit(PointerEventData eventData)
  35. {
  36. lvlMgr.SetLevelDesc("关卡信息");
  37. }
  38.  
  39. public void OnPointerUp(PointerEventData eventData)
  40. {
  41. pressObj.SetActive(false);
  42. }
  43.  
  44. private void Awake()
  45. {
  46. LockObj.SetActive(false);
  47. pressObj.SetActive(false);
  48. }
  49.  
  50. // Use this for initialization
  51. void Start () {
  52. float scale = ;
  53. //初始化关卡数字显示
  54. if (id < )
  55. {
  56. //完全用代码动态创建一个Image对象,并作为num的子节点
  57. GameObject obj = new GameObject("num1",typeof(Image));
  58. RectTransform rtf = obj.GetComponent<RectTransform>();
  59. rtf.SetParent(numTrans);
  60. //设置数字
  61. Image img = obj.GetComponent<Image>();
  62. img.sprite = lvlMgr.spr_nums[id];
  63. img.SetNativeSize(); //图片原始尺寸
  64. rtf.localScale = new Vector3(,,);
  65. rtf.localPosition = Vector3.zero;
  66.  
  67. }
  68. else if (id<)
  69. {
  70. //十位数
  71. GameObject obj = new GameObject("num1", typeof(Image));
  72. RectTransform rtf = obj.GetComponent<RectTransform>();
  73. rtf.SetParent(numTrans);
  74. //设置数字
  75. Image img = obj.GetComponent<Image>();
  76. img.sprite = lvlMgr.spr_nums[id/];
  77. img.SetNativeSize(); //图片原始尺寸
  78. rtf.localScale = new Vector3(, , );
  79. rtf.localPosition = new Vector3(-scale * rtf.rect.width/-,,);
  80.  
  81. //个位数
  82. GameObject obj2 = new GameObject("num2", typeof(Image));
  83. RectTransform rtf2 = obj2.GetComponent<RectTransform>();
  84. rtf2.SetParent(numTrans);
  85. //设置数字
  86. Image img2 = obj2.GetComponent<Image>();
  87. img2.sprite = lvlMgr.spr_nums[id % ];
  88. img2.SetNativeSize(); //图片原始尺寸
  89. rtf2.localScale = new Vector3(, , );
  90. rtf2.localPosition = new Vector3(scale * rtf2.rect.width / + , , );
  91. }
  92. levelInfo = DataMgr.Instance().levelData.levels[id - ];
  93. }
  94.  
  95. // Update is called once per frame
  96. void Update () {
  97.  
  98. }
  99. }

Unity3D_(游戏)卡牌03_选关界面的更多相关文章

  1. Unity3D_(游戏)卡牌02_主菜单界面

      启动屏界面.主菜单界面.选关界面.游戏界面 卡牌01_启动屏界面 传送门 卡牌02_主菜单界面 传送门 卡牌03_选关界面 传送门 卡牌04_游戏界面    传送门 主菜单界面 (选择左边图标或选 ...

  2. Unity3D_(游戏)卡牌01_启动屏界面

      卡牌2D游戏展示 (游戏代码放到  卡牌04_游戏界面  文章最后面~) 游戏项目已托管到github上(里面有个32bit可执行文件) 传送门 规则 开始游戏每张卡牌初始翻开展示 展示几秒后卡牌 ...

  3. Unity3D_(游戏)卡牌04_游戏界面

        启动屏界面.主菜单界面.选关界面.游戏界面 卡牌01_启动屏界面 传送门 卡牌02_主菜单界面 传送门 卡牌03_选关界面 传送门 卡牌04_游戏界面    传送门 选关界面效果 (源代码在文 ...

  4. iOS开发 Swift开发数独游戏(三) 选关界面

    一.选关界面涉及到的功能点 1)需要UITableView以及相应数据代理.协议的实现 2)读取plist文件并转化成模型 3)在单元格点击后进入数独游戏,涉及到把数据经segue在UIViewCon ...

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

    通过前面的开始界面基本上了解了eui的使用方法,可以简单快速的制作一个UI界面,本篇使用第二界面选关界面展示更为难一点的代码控制,来展现关卡地图的内容,请确保素材和资源完整,可以在前面的教程中找到下载 ...

  6. 在WebGL场景中管理多个卡牌对象的实验

    这篇文章讨论如何在基于Babylon.js的WebGL场景中,实现多个简单卡牌类对象的显示.选择.分组.排序,同时建立一套实用的3D场景代码框架.由于作者美工能力有限,所以示例场景视觉效果可能欠佳,本 ...

  7. iOS开发 Swift开发数独游戏(四) 游戏界面的界面与逻辑

    一.游戏界面涉及到的功能点 1)数独格子的建模 (1)绘制数独格子要考虑到标记功能 所以要在每个格子内预先塞入9个标记数字,仅数独格子算下来就有9*9*9=729个格子且存在大量嵌套(这导致我在操作S ...

  8. cocos2d-x 3.3 之卡牌设计 NO.4 定时器的使用(清理内存)

    我的卡牌游戏卡牌有两个类.各自是OpenCard和CardSprite. 不知道分成两个是不是有些奇怪.我分开的原因是:一个卡牌用来当手牌,一个用来当场上的牌,这样说是不是更加奇怪了.. 玩家类里定义 ...

  9. [省选联考 2021 A/B 卷] 卡牌游戏

    垃圾福建垫底选手来看看这题. 大家怎么都写带 \(log\) 的. 我来说一个线性做法好了. 那么我们考虑枚举 \(k\) 作为翻转完的最小值. 那么构造出一个满足条件的操作,我们在 \(a_i\) ...

随机推荐

  1. requests库爬取豆瓣热门国产电视剧数据并保存到本地

    首先要做的就是去豆瓣网找对应的接口,这里就不赘述了,谷歌浏览器抓包即可,然后要做的就是分析返回的json数据的结构: https://movie.douban.com/j/search_subject ...

  2. # Tallest Cows(差分)

    Tallest Cows(差分) n头牛,给出最高牛的位置和身高,其他牛身高未知,给出m对相对关系,表示可以相互看见当且仅当他们中间的牛都比他们矮.求每头牛身高最大值是多少. 差分数组的性质:前缀和为 ...

  3. C++ 对象的构造

    在类里面成员函数的初始值是多少了?(取决于创建对象的位置,是在堆.栈.还是在静态存储区中创建.) 例如: #include <stdio.h> class Test { private: ...

  4. katalon设置Android SDK路径

    本文链接:https://blog.csdn.net/feiniao8651/article/details/82809147文章允许转载,请注明来源:https://blog.csdn.net/fe ...

  5. 分布式的几件小事(三)dubbo的通信协议与序列化

    1.dubbo的通信协议 ①dubbo协议 Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况. 特点 : dubbo缺 ...

  6. ccs之经典布局(二)(两栏,三栏布局)

    接上篇ccs之经典布局(一)(水平垂直居中) 四.两列布局 单列宽度固定,另一列宽度是自适应. 1.float+overflow:auto; 固定端用float进行浮动,自适应的用overflow:a ...

  7. 小P的架构生活(上)

    背景:这年小P已经参加工作4年了,在前同事Z的极力劝说下,小P加入了Z新开的公司Y,公司一共有三个人:老板Z.程序员小P.前台W.项目名为XX交易系统 小P加班加点,终于在两个月后把系统开发完成,版本 ...

  8. 1.device-manage 优化

    一.当前简介 版本信息 device-manage:v1.0 mysql: 5.6.20 jdk : 1.8 Apache Maven 3.3.3 Spring4.2.5.RELEAS+SpingMV ...

  9. centos7.3安装docker

    一.写随笔的原因:最近在阿里云上买了个centos7.3服务器,想将一些demo运行在上面,所以需要做一些环境的安装,通过此篇文章MAKR一下.下面来记录下安装步骤(参考网上的一些教程,有坑的话会实时 ...

  10. 一,Devops核心要点及kubernetes的架构概述

    目录 1,devops的简述及要点 2,kubernetes的简单介绍与组成 特性 集群构成 pod的基本概念 kubernetes网络 1,devops的简述及要点 DevOps,分层架构 ---& ...