设计思想
不管是UGUI和FairyGUI。基本上都会划分各种各样的模块,背包,交易,主界面等等。如果我们对模块不进行流程化管理,则会导致每个模块的代码混乱和臃肿,越到后期,维护越困难。现在比较流行的架构是MVC框架,比如PureMVC,但是PureMVC个人觉得流程还是过于负责,可以借鉴MVC的思想设计一个便捷开发的流程架构。
每一个UI模块,可以划分出类似MVC的架构,我这里是UIProxy UIView Model。每一个都有它各种负责的职责。
1.UIProxy和UIView互相绑定,一个界面都会生成对应的UIProxy,UIProxy负责UI的加载卸载,还有其他跟界面逻辑无关的界面设定。比如定义界面类型:HUD类型,还是一级界面,或者弹窗类型,标记系统Id等等。
2.UIView界面逻辑,只负责界面内的业务,跟UIProxy互相绑定
3.Model数据模型,任意建立一个Model,Model可以全局访问,负责数据类业务,收发网络数据,UI产生的各种数据等等
架构实现
UIProxy
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Frame.UI
{
public interface IProxy
{
bool isTop { get; }
IUI ui { get; }
UISortType SortType();
abstract string GetUrl();
abstract string GetSystemRefId();
Transform rootTr { get; }
void LoadSubProxy<P>() where P : IProxy;
void UnloadSubProxy<P>() where P : IProxy;
//是否已经加载
public bool GetIsLoad();
//UI是否准备好
public bool GetIsUIReady();
//加载
public void Load(params object[] agr);
//移除
public void Unload();
void SetParent(IProxy parent);
IEnumerator StartLoad();
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Frame.UI
{
public abstract class UIProxy<T> : IProxy where T : UI<UIProxy<T>>
{
private LinkedList<IProxy> childProxyArray = new LinkedList<IProxy>();
private Dictionary<string, IProxy> childProxyDic=new Dictionary<string, IProxy>();
private bool isLoad = false;
private bool isUIReady = false;
private Transform m_rootTr;
public abstract UISortType SortType();
public abstract string GetUrl();
public abstract string GetSystemRefId();
public IProxy parent;
public Type lastChildType;
public IUI ui { get; private set; }
public bool isTop
{
get
{
if(parent==null)
return true;
return false;
}
}
public Transform rootTr => m_rootTr;
public T GetUI()
{
return ui as T;
}
//加载界面
public void Load(params object[] agr)
{
if(isUIReady)
{
ui.OnStart();
return;
}
else
{
if (isLoad) return;
isLoad = true;
UIMgr.Instance.Load(this);
if (isTop)
UIProxyMgr.Instance.Load(this);
}
}
public IEnumerator StartLoad()
{
string url = GetUrl();
var request = Resources.LoadAsync<GameObject>(url);
yield return request;
GameObject go = UnityEngine.Object.Instantiate<GameObject>(request.asset as GameObject);
var parentRoot = UIMgr.Instance.GetRoot(SortType());
if (m_rootTr == null)