【Unity】游戏UI框架(基于UGUI)
前⼏天练习写了这⼀套Unity的UI框架,对于游戏开发很实⽤,写篇笔记梳理⼀下⼤致思路
⼯程⽂件见
实际效果
游戏运⾏加载主菜单页⾯
点击对应按钮可以打开具体页⾯,当有具体页⾯的时候主菜单按钮⽆法点击,点击右上⾓的关闭按钮可以关闭该页⾯,关闭页⾯后主菜单按钮继续⽣效
UIFramework基本架构
基本架构如下图所⽰
UIPanel部分
这⼀部分是⽤于描述UI⾯板属性的⼀些类,分别是UIPanelType、UIPanel、BasePanel
UIPanelType
这是⼀个枚举类,⽤于描述UIPanel的种类。在这⾥我写了四种,分别是主菜单⾯板MainMenuPanel、商店⾯板StorePanel、暂停⾯板PausePanel和系统设置⾯板SystemSettingPanel(注意:⾯板的prefab名称需要与枚举类的类型名称相同)
public enum UIPanelType
{
MainMenuPanel,
SystemSettingPanel,
PausePanel,
StorePanel
}
UIPanel
这个类⽤于储存⾯板本⾝⽂件的信息,有两个字段,⼀个字段⽤来描述该⾯板UIPanelType的类型,⼀个字段储存该⾯板prefab⽂件的路径,以便在游戏运⾏时动态实例化⾯板
public class UIPanel
{
public UIPanelType UIPanelType;
public string UIPanelPath;
}
BasePanel
这是所有⾯板上挂载的Script的基类,所以需要继承⾃MonoBehaviour。BasePanel⾥的⽅法⽤来描述所有⾯板共同的⼀些基本⾏为,例如打开与关闭,⽽⾯板的四个状态:进⼊场景OnEnter、暂停OnPause、继续OnResume(解除暂停)、推出场景OnExit也是属于这个类的四个⽅法。
⽅法的具体实现以及其他字段⽅法待后期需要再添加。
using UnityEngine;
using UnityEngine.UI;
public class BasePanel : MonoBehaviour
{
public void OnEnter()
{
}
public void OnPause()
{
}
public void OnResume()
{
}
public void OnExit()
{
}
}
Manager部分
html浮动UIManager
UIManager类的该UI框架的核⼼,它负责的⼯作如下:
1.⾃动更新Json⽂件记载的指定的⾯板prefab⽂件夹下的prefab的UIPanelType与路径
2.使⽤列表储存所有UIPanel
3.使⽤字典储存所有UIPanel上挂载的继承⾃BasePanel的组件/script
4.使⽤栈储存场景中正在显⽰的UIPanel
单例模式
把UIManager做成单例模式
private static UIManager _instance;
public static UIManager Instance
孙侨潞是什么命{
get
{
if(_instance ==null)
_instance =new UIManager();送情郎岳云鹏版
return _instance;
}
游戏辅助框架免root}
1.⾃动更新Json
⾸先引⼊LitJson库,然后引⼊命名空间using LitJson
指定⾯板prefab所存放的⽂件夹,这⾥我放在Resources下的UIPanelPrefab⽂件夹下,⽅便Unity打包与加载
readonly string panelPrefabPath = Application.dataPath +@"/Resources/UIPanelPrefab";
指定Json⽂件所存放的⽂件夹,因为Resources⽂件夹在游戏打包后是只读的,需要写⼊操作的Json⽂件就需要单独另开⼀个⽂件夹,这⾥我放在Json⽂件夹下,Json⽂件命名为UIJson
readonly string jsonPath = Application.dataPath +@"/Json/UIJson.json";
使⽤List列表储存所有的UIPanel
private List<UIPanel> panelList;
写⼀个传⼊Json路径,就可以读取Json⽂件并转换为List类型的列表返回的⽅法
public List<UIPanel>ReadJsonFile(string jsonPath)
{
//如果不到UIJson⽂件,则新建⼀个Json⽂件并写⼊“[]”
//如果仅新建⼀个空Json⽂件,Json转换会返回⼀个null,也就是后⾯的list等于null,之后使⽤list的操作就会报⼀个空指针错误。
if(!File.Exists(jsonPath))
File.WriteAllText(jsonPath,"[]");
List<UIPanel> list = JsonMapper.ToObject<List<UIPanel>>(File.ReadAllText(jsonPath));
return list;
}
再写⼀个传⼊Json路径和List类型的UIPanel的列表,可以把该列表内容写⼊该路径的Json⽂件的⽅法
public void WriteJsonFile(string jsonPath, List<UIPanel> list)
{
string json = JsonMapper.ToJson(list);
File.WriteAllText(jsonPath, json);
}
最后写⾃动更新Json⽂件的⽅法UIPanelInfoSaveInJson()
public void UIPanelInfoSaveInJson()
{
panelList =ReadJsonFile(jsonPath);//读取现有json⾥的UIPanelList
/
/读取储存⾯板prefab的⽂件夹的信息
DirectoryInfo folder =new DirectoryInfo(panelPrefabPath);
//遍历储存⾯板prefab的⽂件夹⾥每⼀个prefab的名字,并把名字转换为对应的UIPanelType
//再检查UIPanelType是否存在于List⾥,若存在List⾥则更新path,若不存在List⾥则加上
foreach(FileInfo file in folder.GetFiles("*.prefab"))
{
UIPanelType type =(UIPanelType)Enum.Parse(typeof(UIPanelType), file.Name.Replace(".prefab",""));
//这⾥的path是相对路径,因为加载时使⽤的是Resources.load
string path =@"UIPanelPrefab/"+ file.Name.Replace(".prefab","");
bool UIPanelExistInList =false;//默认该UIPanel不在现有UIPanelList中
//在List⾥查type相同的UIPanel
//SearchPanelForType是⼀个List的扩展⽅法,具体见Extension部分
UIPanel uIPanel = panelList.SearchPanelForType(type);
if(uIPanel !=null)//UIPanel在该List中,更新path值
{
uIPanel.UIPanelPath = path;
UIPanelExistInList =true;
}
if(UIPanelExistInList ==false)//UIPanel不在List中,加上该UIPanel
grunt胃出血{
UIPanel panel =new UIPanel
{
UIPanelType = type,
UIPanelPath = path
};
panelList.Add(panel);
}
}
WriteJsonFile(jsonPath, panelList);//把更新后的UIPanelList写⼊Json
AssetDatabase.Refresh();//刷新资源
}
UIPanelInfoSaveInJson()需要在UIManager的构造⽅法⾥调⽤,因为需要在游戏运⾏开始就更新Json⽂件,以免后⾯加载的仍然是旧Json⽂件⾥记录的prefab路径
private UIManager()//【单例模式】构造⽅法为私有,UIManager的实例仅能在类内构造
{
//⾃动解析Json⽂件并赋值给panelList
//并使⽤prefab⽂件夹下的信息对panelList进⾏更新,再写⼊json⽂件
UIPanelInfoSaveInJson();
}
使⽤字典储存 ⾯板类型UIPanelType :实例⾯板BasePanel 键值对卵巢囊肿是什么原因
private Dictionary<UIPanelType, BasePanel> panelDict;
开发⼀个给出⾯板类型,就实例化该⾯板,并返回⾯板上挂载的BasePanel组件的⽅法
先获得场景中的Canvas,以便实例化的⾯板设为Canvas的⼦物体
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论