UI框架类图如下:
public class BasePanel : MonoBehaviour
{
///
/// 界面显示出来
///
public virtual void OnEnter() { }
///
/// 界面暂停(弹出了其他界面)
///
public virtual void OnPause() { }
///
/// 界面继续(其他界面移除,回复本来的界面交互)
///
public virtual void OnResume() { }
///
/// 界面不显示,退出这个界面,界面被关闭
///
public virtual void OnExit() { }
}
UIManager.cs
public class UIManager
{
// 单例模式:定义一个静态的对象,构造方法私有化,内部构造,用于外部访问
private static UIManager _instance;
public static UIManager Instance
{
get
{
if (_instance == null)
{
_instance = new UIManager();
}
return _instance;
}
}
//字典存储所有面板的Prefabs路径
private Dictionary panelPathDict = new Dictionary();
//保存所有已实例化面板的游戏物体身上的BasePanel组件
private Dictionary panelDict = new Dictionary();
//存储当前场景中的界面
private Stack panelStack = new Stack();
private Transform canvasTransform;
private Transform CanvasTransform
{
get
{
if (canvasTransform == null)
{
canvasTransform = GameObject.Find("Canvas").transform;
}
return canvasTransform;
}
}
private UIManager()
{
ParseUIPanelTypeJson();
}
///
/// 解析JSON,获取所有面板的路径信息
///
private void ParseUIPanelTypeJson()
{
TextAsset ta = Resources.Load("UIPanelType");
JsonData jsonDataArray = JsonMapper.ToObject(ta.text);
foreach (JsonData item in jsonDataArray)
{
UIPanelType panelType = (UIPanelType)Enum.Parse(typeof(UIPanelType), item["panelType"].ToString());
string path = item["path"].ToString();
panelPathDict.Add(panelType, path);
}
}
///
/// 根据面板类型,返回对应的BasePanel组件
///
/// 需要返回的面板类型
/// 返回该面板组件
private BasePanel GetPanel(UIPanelType panelType)
{
BasePanel basePanel = panelDict.GetValue(panelType);
//如果panel为空,根据该面板prefab的路径,实例化该面板
if (basePanel == null)
{
string path = panelPathDict.GetValue(panelType);
GameObject newPanel = GameObject.Instantiate(Resources.Load(path)) as GameObject;
newPanel.transform.SetParent(CanvasTransform, false);
//第一次实例化的面板需要保存在字典中
panelDict.Add(panelType, newPanel.GetComponent());
return newPanel.GetComponent();
}
else
{
return basePanel;
}
}
///
/// 设置默认的栈顶元素
///
/// 界面类型
/// 组件
public void SetDefaultPopPanel(UIPanelType panelType,BasePanel basePanel)
{
panelDict.Add(panelType, basePanel);
panelStack.Push(basePanel);
}
///
/// 把该页面显示在场景中
///
/// 需要显示界面的类型
public void PushPanel(UIPanelType panelType)
{
//判断一下栈里面是否有页面
if (panelStack.Count > 0)
{
panelStack.Peek().OnPause();//原栈顶界面暂停
}
BasePanel panel = GetPanel(panelType);
panel.OnEnter();//调用进入动作
panelStack.Push(panel);//页面入栈
}
///
/// 关闭栈顶界面显示
///
public void PopPanel()
{
//当前栈内为空,则直接返回
if (panelStack.Count <= 0) return;
panelStack.Pop().OnExit();//Pop删除栈顶元素,并关闭栈顶界面的显示,
if (panelStack.Count <= 0) return;
panelStack.Peek().OnResume();//获取现在栈顶界面,并调用界面恢复动作
}
}
public enum UIPanelType
{
ItemMessagePanel,
CharacterPanel,
KnapsackPanel,
MainMenuPanel,
ShopPanel,
SkillPanel,
SystemPanel,
TaskPanel
}
[
{
"panelType": "ItemMessagePanel",
"path": "UIPanel/ItemMessagePanel"
},
{
"panelType": "CharacterPanel",
"path": "UIPanel/CharacterPanel"
},
{
"panelType": "KnapsackPanel",
"path": "UIPanel/KnapsackPanel"
},
{
"panelType": "ShopPanel",
"path": "UIPanel/ShopPanel"
},
{
"panelType": "SkillPanel",
"path": "UIPanel/SkillPanel"
},
{
"panelType": "SystemPanel",
"path": "UIPanel/SystemPanel"
},
{
"panelType": "TaskPanel",
"path": "UIPanel/TaskPanel"
}
]
public void OnPushPanel(string panelTypeString)
{
UIPanelType panelType = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), panelTypeString);
UIManager.Instance.PushPanel(panelType);
}
using UnityEngine;
using DG.Tweening;
public class CharacterPanel : BasePanel
{
private CanvasGroup canvasGroup;
void Start()
{
if (canvasGroup == null) canvasGroup = GetComponent();
}
public override void OnEnter()
{
if (canvasGroup == null) canvasGroup = GetComponent();
canvasGroup.alpha = 1;
canvasGroup.blocksRaycasts = true;
Vector3 temp = transform.localPosition;
temp.x = -800;
transform.localPosition = temp;
transform.DOLocalMoveX(0, 0.5f);
}
public override void OnPause()
{
canvasGroup.blocksRaycasts = false;
}
public override void OnResume()
{
canvasGroup.blocksRaycasts = true;
}
public override void OnExit()
{
transform.DOLocalMoveX(-800, .5f).OnComplete(() => canvasGroup.alpha = 0);
}
public void OnClosePanel()
{
UIManager.Instance.PopPanel();
}
}
其他界面代码实现类似,可以自己实现不同的切换效果。觉得我分享的学习博客有用的话,记得点赞关注我哦!
源文件百度云链接:链接:https://pan.baidu.com/s/1r-4AKfeO1WxUiENuo1lLLQ 密码:vrs1