简单的UI框架
控制界面出栈和界面的隐藏关闭
控制界面出栈和界面的隐藏关闭
界面出栈就是把界面给关闭。
在我们UIManager的PopPanel方法内
public void PopPanel()
{
}
我们直接调用我们的OnExit方法就可以了。
首先判断栈是否为空,为了安全。
然后判断栈里面有没有界面,没有界面直接return。
不为空我们直接取出栈顶元素,调用Pop方法出栈,然后调用我们的OnExit方法将他移除栈。
public void PopPanel()
{
if (panelStack == null)
panelStack = new Stack<BasePanel>();
if (panelStack.Count <= 0) return;
///关闭栈顶页面的显示
BasePanel topPanel = panelStack.Pop();
topPanel.OnExit();
}
关闭栈顶的界面之后,应该显示栈顶下面的界面。
首先判断栈顶下面有没有页面。
然后调用Peek方法取到现在的栈顶,然后调用我们的OnResume方法。
public void PopPanel()
{
if (panelStack == null)
panelStack = new Stack<BasePanel>();
if (panelStack.Count <= 0) return;
///关闭栈顶页面的显示
BasePanel topPanel = panelStack.Pop();
topPanel.OnExit();
if(panelStack.Count <= 0) return ;
BasePanel topPanel2 = panelStack.Peek();
topPanel2.OnResume();
}
现在我们回到Unity中,我们打开任务面板
我们现在要处理点击右上角的×,任务界面被关闭。
打开我们任务界面的脚本。
我们定义一个界面关闭的方法,直接调用我们刚才的PopPanel方法就可以了。
public void OnClosePanel()
{
UIManager.Instance.PopPanel();
}
定义完之后,我们在任务界面的按钮上添加这个方法。
现在我们运行游戏,发现点击×界面没有被关闭,因为我们只是完善了框架里面的内容,我们的OnExit方法是没有实际操作的。
所以接下来在任务界面脚本中重写这个方法。
我们怎么实现界面的关闭呢?
我们可以选择直接将他隐藏掉当然也可以使用SetActive方法。
在我们的任务界面添加CanvasGroup组件。
这里的Alpha设置为0时界面被隐藏掉,为1时界面显示。
所以我们把Alpha设置为0,BlocksRaycasts设置为false就可以了。
我们第一步先要得到这个组件,然后再Start方法中取到,最后再重写的方法中实现即可。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TextPanel : BasePanel
{
private CanvasGroup canvasGroup;
private void Start()
{
canvasGroup = GetComponent<CanvasGroup>();
}
/// <summary>
/// 处理面板关闭
/// </summary>
public override void OnExit()
{
canvasGroup.alpha = 0;
canvasGroup.blocksRaycasts = false;
}
public void OnClosePanel()
{
UIManager.Instance.PopPanel();
}
}
现在我们在运行一次,发现界面确实被关闭了,但是我们的主界面不能实现交互了。
这时候就要用到我们的OnResume方法,方法表示让我们的界面继续交互。
因为是让我们的主界面继续交互,所以回到我们的MainMemuPanle脚本中。
我们重写OnResume方法,将BlocksRaycasts设置为true就可以了。
public override void OnResume()
{
canvasGroup.blocksRaycasts = true;
}
我们再运行一下游戏,此时主界面可以交互了,但是我们的任务界面无法再次打开。
这个是因为我们第一次点击任务是,任务界面被实例化出来,默认是显示的,当我们点击×后,Alpha被设置为0,BlocksRaycasts被设置为false了,当我们再点击的时候,因为这个面板还是存在我们的场景中的,他会调用OnEnter方法,但是这个方法没有内容,就没有办法显示出来,所以这里我们要重写这个OnEnter方法。
public override void OnEnter()
{
canvasGroup.alpha = 1;
canvasGroup.blocksRaycasts = true;
}
我们再运行的时候,报了一个空指针的错误。
是因为当我们把任务界面实例化出来的时候,会立马调用OnEnter方法,这个时候Start方法还没有被调用,所以说canvasGroup是为空的。
所以我们对脚本进行更改,我们可以在重写的OnEnter方法内定义canvasGroup。
所以判断一下当canvasGroup为空的时候,获取这个组件。
private void Start()
{
if (canvasGroup == null)
canvasGroup = GetComponent<CanvasGroup>();
}
public override void OnEnter()
{
if (canvasGroup == null)
canvasGroup = GetComponent<CanvasGroup>();
canvasGroup.alpha = 1;
canvasGroup.blocksRaycasts = true;
}
这样我们在运行,现在就没有任何问题了!
总结
我们对界面的出栈操作进行了完善,同时也实现了恢复主界面的暂停,即主界面不与鼠标交互。