图源/网络

接下来实现弹窗功能。

首先,需要明确的是,这边所说的弹窗到底是什么?

此处所说的弹窗,指的是非主界面的所有弹出窗口,里面包括一些界面,比如系统设置、科技界面等。

这些窗口打开的时候,主界面依然是存在的,并且可能作为UI的背景之一,因为这些UI会比主界面要小一些。

并且,很可能同一时间会打开多个弹窗,比如最典型的的,我在科技树弹窗上,选择提升某个科技,这时候会弹出一个确认的新弹窗,并且前面那个科技树弹窗还存在。

为了便于操作,可以定这样的规则:

弹窗上操作可以弹出新的弹窗,但是玩家只能操作最新出现的那个弹窗。

继续回到科技树那个例子上,我在科技树上选择了科技A,这时弹出了一个窗口,让我确认是否花费xxx升级科技A。

这时候,有些游戏是可以不点那个确认窗口,继续点科技树上的科技B的。点完后,那个确认弹窗的文字会变成“是否花费xxx升级科技B”。

而我简化了一下这个操作并规定,这时候玩家只能操作那个确认弹窗界面,要么点取消,要么点确认。玩家想要改升级科技B,需要先点取消把弹窗关闭,然后再选择科技B。

当然,如果以后觉得可以优化体验,可以改成前面说的这种,多个窗口并存的模式,但不是现在。这么一来,逻辑就简单多了,方面快速把游戏原型给做出来。

接下来是具体功能的实现,首先是修改游戏的参数名:

  1. public class UIRoot: MonoBehaviour {
  2. ……
  3. private readonly Dictionary<UIType, BaseUI> uiDic = new Dictionary<UIType, BaseUI>();
  4. private readonly Stack<BaseUI> CurrentAboveUI = new Stack<BaseUI>();
  5. ……
  6. }

复制代码

将原来的NormalUIDic重命名为UIDic。因为接下来,弹窗的UI也将存放到这个字典中。

同时新建一个Stack用于存放正在使用的UI,类似于上一篇文章中的CurrentUI。

Stack类型即堆栈,有点类似于List,用于存放多个相同类型的对象。和List不同的是,他的存储是先进先出的,即我按A-B-C的顺序依次存入一个Stack之后,我要取出,必然只能是C-B-A。这一特点和弹窗的设计是一致的。

Stack的用法很简单,这里主要用到了下面几个方法:

  1. Stack<a> aStack = new Stack<a>();//创建一个a类型的堆栈
  2. int count = aStack.Count;//获取堆栈中元素的个数
  3. a newA = new a();
  4. aStack.Push(newA);//将一个元素存放进堆栈
  5. a theA = aStack.Pop();//获得堆栈中最新存进去的元素,并在堆栈中删除它

复制代码

于是,我们可以模仿文章中如何打开一个新界面的方法写如何打开一个弹窗:

  1. private readonly Stack<BaseUI> CurrentAboveUI = new Stack<BaseUI>();
  2. public void OpenKeepAboveUI(UIType uiType)
  3. {
  4. BaseUI theUI;
  5. if (UIDic.ContainsKey(uiType))
  6. {
  7. theUI = UIDic[uiType];
  8. }
  9. else
  10. {
  11. theUI = Instantiate(Resources.Load<BaseUI>(UIConfig.UIPath[uiType])) as BaseUI;
  12. UITool.AddChild(theUI.transform, KeepAboveUI);
  13. UIDic.Add(uiType, theUI);
  14. }
  15. CurrentAboveUI.Push(theUI);//将theUI放入堆栈
  16. theUI.transform.SetAsLastSibling();//将该界面放在最上面那一层
  17. theUI.OpenUI();
  18. }

复制代码

和主界面不同的是,由于主界面是互斥的,所以主界面没有单独必要写一个关闭主界面的函数。但弹窗需要:

  1. public void CloseKeepAboveUI()
  2. {
  3. if (CurrentAboveUI.Count == 0)
  4. {
  5. return;
  6. }
  7. BaseUI theUI = CurrentAboveUI.Pop();//获得最上一层的UI,并在堆栈中删除它
  8. theUI.CloseUI();
  9. }

复制代码

这个方法用来删除最上层的弹窗,毕竟在设计中,弹窗只能操作最上面的那个。

好了,现在可以做几个界面来测试一下:

先右键UIRoot下Keep Above UI这个gameobject,然后选择创建一个新的Panel,并重命名为Test Above UI

然后再在这个Panel上,放2个image和2个button,组成一个最简单的UI。这个UI包括背景(用于填充整个窗口以防止点击到主界面上的按钮上去),窗口本体,关闭按钮,打开新弹窗的按钮。

其中NewUIButton是中间蓝色的那个,手游账号拍卖用于打开另一个新的弹窗(这个弹窗还没做),黄色按钮为关闭按钮即CloseButton。

建立一个新的脚本,叫TestAboveUI,并让它继承自BaseUI,并加入以下代码,以实现关闭窗口的功能:

  1. public class TestAboveUI : BaseUI
  2. {        private Button CloseButton;
  3. private void Awake()
  4. {
  5. CloseButton = UITool.FindChildByName(gameObject, "CloseButton").GetComponent<Button>();
  6. CloseButton.onClick.AddListener(CloseThisUI);
  7. }
  8. public void CloseThisUI()
  9. {
  10. UIRoot.Instance.CloseKeepAboveUI();
  11. }
  12. }

复制代码

挂在刚刚我们建的那个窗口上。

将该窗口做成prefab放在其他的窗口prefab一起。

在UIConfig文件中添加对应的索引:

  1. public class UIConfig
  2. {
  3. public static Dictionary<UIType, string> UIPath = new Dictionary<UIType, string>
  4. {
  5. { UIType.StartUI,"UIPrefabs/StartUI"},
  6. { UIType.GameSettingUI,"UIPrefabs/GameSettingUI"},
  7. { UIType.TestAboveUI,"UIPrefabs/TestAboveUI"},
  8. };
  9. }

复制代码

我们再打开文章中做的GameSettingUI,并添加一个新的Button,名叫OpenTestUI。

打开GameSettingUI的脚本,添加该按钮相关的代码:

  1. public class GameSettingUI : BaseUI {
  2. ……
  3. private Button openTestUI;
  4. private void Awake()
  5. {
  6. ……
  7. openTestUI = UITool.FindChildByName(gameObject, "OpenTestUI").GetComponent<Button>();
  8. openTestUI.onClick.AddListener(OpenTestUI);
  9. }
  10. ……
  11. public void OpenTestUI()
  12. {
  13. UIRoot.Instance.OpenKeepAboveUI(UIType.TestAboveUI);
  14. }
  15. }

复制代码

原理已经讲过了,就不展开说了。

运行程序,可以在GameSettingUI窗口中,打开弹窗,然后点击黄色按钮关闭。

从零开始做一个SLG游戏(五):UI系统之弹窗功能相关推荐

  1. 从零开始做一个SLG游戏(四):UI系统之主界面搭建

    地图部分也已经算是可以告一段落了,也需要仔细考虑下接下来该做哪个系统.地图部分可以算是六边形地图的SLG游戏最主要的一部分,所以先做了下练练手. 接下来的工作更多的需要从项目的全局角度来考虑该怎么做. ...

  2. 城市代码表_从零开始做一个SLG游戏(六)游戏系统以及配置表

    本文主要是来梳理下游戏内的基本系统(虽然只是照搬polytopia的,但是还是要总结一下),并预先做一些配置表,并实现读取. 一.经济系统 1.总述 经济系统可以是整个游戏的核心.在本游戏中只有一种资 ...

  3. 从零开始做一个SLG游戏(七):游戏系统以及配置表

    本文主要是来梳理下游戏内的基本系统(虽然只是照搬polytopia的,但是还是要总结一下),并预先做一些配置表,并实现读取. 一.经济系统 1.总述 经济系统可以是整个游戏的核心.在本游戏中只有一种资 ...

  4. freemarker 去掉最后一个逗号_从零开始做一个SLG游戏(六)游戏系统以及配置表...

    本文主要是来梳理下游戏内的基本系统(虽然只是照搬polytopia的,但是还是要总结一下),并预先做一些配置表,并实现读取. 一.经济系统 1.总述 经济系统可以是整个游戏的核心.在本游戏中只有一种资 ...

  5. 从零开始做一个SLG游戏(二):用mesh实现简单的地形

    本文主要是用mesh实现简单的地形.暂时先绘制三种地形:高山.平原.水域. 首先要做的是网格的细化: 上一篇已经实现了单个六边形的绘制,实现方式是将六边形分割成6个等边三角形,然后分别绘制. 现在需要 ...

  6. 从零开始做一个SLG游戏(一):六边形网格

    本文的主要工作是六边形网格的绘制. 如图所示.六边形有6个方向,6个顶点,同时定义中心点到边的最短距离为内径innerRadius,定义中心点到顶点的距离为外径outerRadius. 六边形可以拆分 ...

  7. 从零开始做一个SLG游戏(三):用unity绘制图形

    本文主要是使用mesh制作一些简单的模型资源. 一般而言,模型的制作最好还是使用专业的软件来做,但是制作一些简单的模型,unity还是可以胜任的. unity自带的模型只有立方体,圆柱,球,胶囊,方块 ...

  8. opencv交通标志识别_教你从零开始做一个基于深度学习的交通标志识别系统

    教你从零开始做一个基于深度学习的交通标志识别系统 基于Yolo v3的交通标志识别系统及源码 自动驾驶之--交通标志识别 在本文章你可以学习到如何训练自己采集的数据集,生成模型,并用yolo v3算法 ...

  9. 做一个FLASH游戏你需要掌握的东西【实用】

    做一个FLASH游戏你需要掌握的东西 作者:jianzhong 一直想着什么时间好好做一个像样点的游戏,于是刻意的开始去了解FLASHGAME的相关资料,在这里把自己在整个制作和收集过程中的一些感觉使 ...

最新文章

  1. 使用NSCondition实现多线程同步
  2. python函数参数*args和**args
  3. linux 更改文件所有者
  4. 【Java例题】5.3 线性表的使用
  5. 内存泄露 内存溢出 内存碎片
  6. 关于STM32 IAP
  7. PAT 1044. 火星数字
  8. SCUT - 254 - 欧洲爆破 - 概率dp - 状压dp
  9. android.bg,[Android]AMS-PSS
  10. XP下如何引导Vista
  11. 【渝粤教育】电大中专职业应用写作 (2)_1作业 题库
  12. fedora9 换源方法
  13. 前端实现拖动滑块完成验证
  14. aptana php 调试,AptanaStudio3+PHP程序远程调试的方法和步骤
  15. easyexcel一个单元格导出多张图片等
  16. 计算机英语 自我介绍,计算机专业英文自我介绍
  17. unity 裙子摆动_随风摆动的草丛——Unity shader graph 2D初探
  18. 大数据项目之电商分析平台(2)
  19. 浅谈二层交换安全攻防
  20. word2013插入excel对象报错_excel插入对象文件夹 Excel2013中插入对象文件的方法

热门文章

  1. 计算机关机电路,电脑顺序开、关机控制电路(一)
  2. KBEngine(CBE)引擎研究 (一) 启动正确的进程
  3. 上网也低碳 使用电脑省电的方式
  4. 公司无故辞退员工应该怎么赔偿
  5. 骁龙 730 正式发布:这回高通不挤牙膏了,还为游戏玩家带来大福利
  6. 【华为2021秋招】【数字IC】【FPGA逻辑】【笔试解析】【独家】【2021届秋招】【FPGA探索者】【DengFengLai123】
  7. 重装win7系统后,连不上网,插入网线没有反应,没有网卡驱动,附驱动下载地址
  8. 【网络安全】Cloudopt Extension - 5分钟告诉你强在哪
  9. Ubuntu修改密码和用户名
  10. 月签电子合同3万+份,电子合同助力高空作业租赁商“大黄蜂”数字化