unity UI 多个次级界面返回逻辑 (新加悔步骤)
·
主要是利用Stack<T>();
堆栈(Stack)代表了一个后进先出的对象集合。
当需要对各项进行后进先出的访问时,则使用堆栈。
当在列表中添加一项,称为推入元素,
增加对象时要压入(push)
当从列表中移除一项时,称为弹出元素。
删除对象时要弹出(pop)
Stack 类的方法和属性
Count,代表了Stack中的元素个数
Clear(),清除所有Stack中的元素
Contains(Obj),判断obj(代表元素)是否存在于stack中
Peek(),返回在 Stack 的顶部的对象,但不移除它
Pop(),移除并返回在 Stack 的顶部的对象
Push( obj ),向 Stack 的顶部添加一个对象
ToArray(),复制所有的stack元素到一个数组中
————————————————

使用 堆栈(Stack)代表了一个后进先出的对象集合
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
[System.Serializable]
public class PeekPopEcent : UnityEvent<bool>
{
}
/// <summary>
/// UI 多个次级界面返回逻辑 管理
/// </summary>
public class UIBackManage : MonoSingleton<UIBackManage>
{
/// <summary>
/// 委托
/// </summary>
public delegate void OnBackDelegate();
Stack<OnBackDelegate> _OnBackStack = new Stack<OnBackDelegate>();
[HideInInspector]
public PeekPopEcent PeekPopAction;
/// <summary>
/// 临时存储(悔棋步骤)
/// </summary>
OnBackDelegate temporaryBD ;
void Awake()
{
PeekPopAction = new PeekPopEcent();
PeekPopAction.AddListener((b) =>{
OnBack02(b);
});
}
/// <summary>
/// 注册(向 Stack 的顶部添加一个对象)
/// </summary>
/// <param name="offAction"> 执行 关闭当前A界面,打开的B界面</param>
/// <param name="openAction">注册 关闭B界面,打开A界面</param>
public void OnCallPushOnBack(Action offAction, Action openAction)
{
//执行 关闭当前A界面,打开的B界面 (要打开的界面)
offAction.Invoke();
PushOnBack(() => {
//注册 关闭B界面,打开A界面 (返回的界面)
openAction.Invoke();
});
}
/// <summary>
/// 调用(移除并返回在 Stack 的顶部的对象)
/// 效果:关闭B界面,打开A界面
/// </summary>
public void OnBack()
{
if (_OnBackStack.Count > 0)
{
OnBackDelegate BD = _OnBackStack.Pop();
temporaryBD = BD;
if (BD != null)
{
BD();
}
}
}
/// <summary>
/// 悔棋,并重新注册
/// </summary>
/// <param name="bo"></param>
public void OnBack02(bool bo)
{
if (temporaryBD!=null)
{
if (!bo)
{
PushOnBack(temporaryBD);
}
}
}
/// <summary>
/// 清除所有Stack中的元素,返回顶部
/// </summary>
/// <param name="offAllAction"></param>
public void OffClearAllBackStack(Action offAllAction)
{
//返回顶部
PopOnBack();
// 清除所有Stack中的元素
ClearOnBackStack();
//关闭当前所有界面
offAllAction.Invoke();
}
/// <summary>
/// 注册 (向 Stack 的顶部添加一个对象)
/// </summary>
/// <param name="cb"></param>
public void PushOnBack(OnBackDelegate cb)
{
_OnBackStack.Push(cb);
}
/// <summary>
/// 移除并返回在 Stack 的顶部的对象
/// </summary>
public void PopOnBack()
{
if (_OnBackStack.Count > 0)
{
_OnBackStack.Pop();
}
}
/// <summary>
/// 清除所有Stack中的元素
/// </summary>
public void ClearOnBackStack()
{
_OnBackStack.Clear();
}
}
using UnityEngine;
/// <summary>
/// 通用Mono单例模板
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
private static T ms_instance;
public static T Instance
{
get
{
if (ms_instance == null)
{
ms_instance = Instantiate();
}
return ms_instance;
}
}
protected static T Instantiate()
{
if (ms_instance != null) return ms_instance;
// 在场景中查找T类型的Mono类
ms_instance = (T)FindObjectOfType(typeof(T));
if (FindObjectsOfType(typeof(T)).Length > 1)
{
return ms_instance;
}
if (ms_instance != null) return ms_instance;
// 创建GameObject实例
var singleton = new GameObject("[Singleton]" + typeof(T).Name);
DontDestroyOnLoad(singleton); // 设置GameObject不被销毁
if (singleton == null) return ms_instance;
// 添加Mono单例脚本
ms_instance = singleton.AddComponent<T>();
// 初始化单例
ms_instance.InitSingleton();
return ms_instance;
}
protected virtual void InitSingleton()
{
}
/// <summary>
/// 使用预制体实例化时创建单例
/// </summary>
protected virtual void Awake()
{
if (ms_instance == null)
{
ms_instance = this as T;
// 初始化单例
InitSingleton();
}
else
{
// 如果已经存在实例,则需要销毁当前的GameObject
GameObject.Destroy(this.gameObject);
}
}
protected virtual void OnApplicationQuit()
{
ms_instance = null;
// 销毁GameObject
GameObject.Destroy(this.gameObject);
}
}
-
注册
UIBackManage.Instance.OnCallPushOnBack(
() => { //1.关闭当前A界面,打开的B界面
ControlCenter.Instance.SetState(true);
this.gameObject.SetActive(false);
},
() => {
//2.注册返回按钮事件 关闭B界面,打开A界面
//关闭B界面,打开A界面
Step_Mgr.Instance.CalculateAccomplishEvent(0, 0, 0, () => {
ControlCenter.Instance.SetState(false);
this.gameObject.SetActive(true);
}, 1);
});
-
调用

//调用前 显示返回按钮
/// <summary>
/// 设置 两个按钮的显示 false=显示返回按钮
/// </summary>
public void SetBtn(bool bo)
{
CaoZuoJiLuBtn.gameObject.SetActive(bo);
ReturnBtn.gameObject.SetActive(!bo);
}
//"返回按钮" 调用
//调用 效果:关闭B界面,打开A界面
UIBackManage.Instance.OnBack();
//悔棋调用
//列如 点击了 "返回"
//1.弹出提示框UI
//2.UI提示 “是否返回”
//3.按钮 是 按钮 否
//4.点击 “是” 正常返回
//5.点击 “否” 重新注册 此返回事件(因为弹出提示框,就已经使用的注册的返回事件)
//列子:
//下方提示框 函数逻辑顺序:
TipDialog.Instance.ShowDialog(strTitle, (bo) =>
{
if (bo)
{
//点击“是” 执行 正常返回
}
else
{
//点击“否” 执行 关闭提示框,重新注册返回事件
Debug.Log("悔一步棋");
UIBackManage.Instance.PeekPopAction.Invoke(false); //注册返回事件
}
}
-
回到主页面大厅,不需要返回 ,则需要清除
//返回顶部
UIBackManage.Instance.PopOnBack();
// 清除所有Stack中的元素
UIBackManage.Instance.ClearOnBackStack();
//关闭当前所有界面
Off();
更多推荐



所有评论(0)