UI的简单框架
json文件:
{
"infoList":
[
{
"panelTypeString":"MainMenu",
"path":"Prefab/UI/MainMenuPanel"
},
{
"panelTypeString":"Character",
"path":"Prefab/UI/CharacterPanel"
},
{
"panelTypeString":"Bag",
"path":"Prefab/UI/BagPanel"
},
{
"panelTypeString":"Task",
"path":"Prefab/UI/TaskPanel"
},
{
"panelTypeString":"Skill",
"path":"Prefab/UI/SkillPanel"
},
{
"panelTypeString":"ItemMessage",
"path":"Prefab/UI/ItemMessagePanel"
},
{
"panelTypeString":"Shop",
"path":"Prefab/UI/ShopPanel"
},
{
"panelTypeString":"System",
"path":"Prefab/UI/SystemPanel"
}
]
}
首先定义一个UIPanelType的枚举类型用来存储UI的类型(例如:背包(Bag))
public enum UIPanelType
{
MainMenu,
Task,
Shop,
Bag,
Skill,
System,
ItemMessage,
Canvas,
}
给字典类添加一个方法
public static class DictionaryExtension
{
public static Tvalue TryGet<Tkey,Tvalue>(this Dictionary<Tkey,Tvalue>,Tkey key)
{
Tvalue value;
dict.TryGetValue(key,out value);
return value;
}
}
随后定义一个UIPanelInfo类用来存储从json文件中读取到的数据
using System;
[Serializable]//这里是进行序列化
public class UIPanelInfo:ISerializationCallbackReceiver//继承序列化的接口
{
[NonSerialized]//反序列化
public UIPanelType type panelType;
//panelTypeString 和 path名字是和json文件中存储的类型名一一对应
public string panelTypeString;
public string path;
//反序列化前调用这个方法
public void OnAfterDeserialize()
{
//把反序列化的字符串类型转化为对应的枚举类型以方便后续的等号操作
panelType = (UIPanelType)Enum.Parse(typeof(UIPanelType), panelTypeString);
}
}
随后再定义一个UIPanelTypeJson类用集合存储每一个UIPanelInfo
[Serializable]
class UIPanelTypeJson
{
//注意:C#中的集合要和json中的集合名字要一致,且也需要标志上序列化
public List<UIPanelInfo> infoList;
}
最后定义一个UIManager类用来管理UI
private Dictionary<UIPanelType, string> panelPathDict;//保存所有面板路径
//BasePanel是自己定义的面板类型的基类,所有面板的父类
private Dictionary<UIPanelType, BasePanel> panelDict;//保存实例化后的面板
//单例模式
private static UIManager _instance;
public static UIManager Instance
{
get
{
if (_instance == null)
{
_instance = new UIManager();
}
return _instance;
}
}
//获取画布
private GameObject canvasTransform;
private GameObject CanvasTransform
{
get
{
if (canvasTransform == null)
{
string path = panelPathDict.TryGet(UIPanelType.Canvas);
canvasTransform = GameObject.Instantiate(Resources.Load(path)) as GameObject;
}
return canvasTransform;
}
}
//构造函数
private UIManager()
{
ParseUIPanelTypeJson();
}
//编译json文件
void ParseUIPanelTypeJson()
{
//判空处理
if(panelPathDict==null)
{
panelPathDict = new Dictionary<UIPanelType,string>();
}
//获取json文件中的文本内容
TextAsset ta = Resources.Load<TextAsset>("UIPanelTrpe");
//通过Unity内置函数将json文件编译存储到jsonObject中
UIPanelTypeJson jsonObject = JsonUtility.FromJson<UIPanelTypeJson>(ta.text);
//遍历jsonObject中的infoList集合中的数据
foreach(UIPanelInfo info in jsonObject.infoList)
{
//把类型和地址存储到字典中
panelPathDict.Add(info.panelType,info.path);
}
}
//根据面板类型来进行实例化
void GetPanel(UIPanelType panelType)
{
//判空处理
if(panelDict==null)
{
panelDict = new Dictionary<UIPanelType, BasePanel>();
}
//在字典中获取面板
BasePanel panel= panelDict.TryGet(panelType);
//如果面板不在字典中
if(panel==null)
{
//获取路径
string path=panelPathDict.TryGet(panelType);
//如果路径存在
if(path != null)
{
GameObject instPanel = GameObject.Instantiate(Resources.Load(path)) as GameObject;//实例化面
instPanel.transform.SetParent(CanvasTransform.transform, false);//把面板设置到画布下
AddScriptsComponent(panelType, instPanel);//动态挂载每一个类型面板对应的脚本
panelDict.Add(panelType, instPanel.GetComponent<BasePanel>());//添加到字典中
}
}
}
void AddScriptsComponent(UIPanelType panelType, GameObject panel)
{
switch (panelType)
{
case UIPanelType.MainMenu:
panel.AddComponent<MainMenuPanel>();
break;
case UIPanelType.Task:
panel.AddComponent<TaskPanel>();
break;
case UIPanelType.Shop:
panel.AddComponent<ShopPanel>();
break;
case UIPanelType.Bag:
panel.AddComponent<BagPanel>();
break;
case UIPanelType.Skill:
panel.AddComponent<SkillPanel>();
break;
case UIPanelType.System:
panel.AddComponent<SystemPanel>();
break;
case UIPanelType.ItemMessage:
panel.AddComponent<ItemMessagePanel>();
break;
default:
break;
}
}
最后在其他脚本中可以通过UIManage.Instance的单例来访问调用函数。