UI简易框架的学习笔记

一、首先这篇文章我是参考麦子学院的一个Unity3D制作3D塔防游戏的其中的UI部分编写的,老师很不错,给了我很大的启发,

在此记录下,主要为了日后的查阅,先讲讲思路吧!


二、为何需要搭建框架?需要哪些条件?具备哪些功能?是否具有拓展性呢?

围绕上面的问题,开始一一阐述吧。


三、总所周知,一个游戏稍微复杂点都会涉及到众多的UI界面,而每个界面上有各种交互性和非交互性的UI控件,当随着游戏的不断迭代,

管理这些UI界面和控件的难度将不断增大,框架能够大大的简化、拓展和维护整个UI系统,学习它是必然的。


四、需要的基本条件有三个。1. Resources下保存各个UI界面的预制体 2.每个UI界面有一个主脚本,而此脚本的名称必须和预制体名称一致 

3.每个UI界面根控件应该覆盖整个画布


五、1.该UI框架在初始时加载主界面,2.然后以主界面为桥梁可以通过界面上的交互控件动态到任意界面,3.当加载新的界面时,前一个界面销毁,

能够节省内存,4.所有游戏界面继承自UIPanel类,只需继承或者重写其父类的方法,即可实现打开其他界面,关闭当前界面,关闭其他界面等。。。

5.UIPanel类同样封装了交互控件的注册和绑定细节,其他界面只需按照所需添加控件,并给控件自定义响应方法即可。


六、该框架是具备拓展性的,1.可以结合Json,动态从本地文件中读取出UI界面,2.每个界面通过重写可以实现自身独有功能

-------------------------------------------

理论部分告一段落,接下来贴出一部分代码来直观的了解下吧。

public class Main : MonoBehaviour {
    void Start () {
        UIManager.OpendPanel<UIMainPanel>();
    }
}该脚本挂在空对象UIManager上,负责加载主界面

public class UIManager : MonoBehaviour
{
    public static List<MonoBehaviour> UIPanelList = new List<MonoBehaviour>();
    public static int flag;

    private static GameObject soleCanvas;
    private const string UIPrefabsLoad = "UIPrefabs/";

    public static void OpendPanel<T>() where T : MonoBehaviour
    {
        if (soleCanvas == null)
        {
            soleCanvas = GameObject.Find("Canvas");
        }
        var assetsUIPanle = Resources.Load(UIPrefabsLoad + typeof(T).Name.ToString()) as GameObject;//动态加载UI面板
        var currentUIPanle = Instantiate(assetsUIPanle);    //实例化UI面板到场景中

        currentUIPanle.transform.SetParent(soleCanvas.transform);//动态加载出来的UIPanle放置到唯一Canvas下

        (currentUIPanle.transform as RectTransform).anchoredPosition = Vector3.zero;    //初始ui面板各项参数
        (currentUIPanle.transform as RectTransform).anchoredPosition3D = Vector3.zero;
        (currentUIPanle.transform as RectTransform).anchorMin = Vector2.zero;
        (currentUIPanle.transform as RectTransform).anchorMax = Vector2.one;
        (currentUIPanle.transform as RectTransform).pivot = new Vector2(0.5f, 0.5f);
        (currentUIPanle.transform as RectTransform).sizeDelta = Vector2.zero;

        var currentUIPanelScript = currentUIPanle.gameObject.AddComponent<T>();//动态加载和UI面板同名的脚本对象

        UIPanelList.Add(currentUIPanelScript);//添加到UI面板列表中

        flag += 1;//用来标记上一个UI面板的索引
    }
}
上面是主要脚本之一,它可以用来动态加载任意指定UI界面,本身是一个泛型方法,T类型由调用者指定,当类型确定时,那么就加载与类型名称

相对应的UI界面,并且将相同名称的脚本动态挂在该界面上。

public class UIPanel : MonoBehaviour
{
    /// <summary>
    /// 递归获取根UI对象及其子UI对象
    /// </summary>
    /// <param name="tran">根UI对象</param>
    /// <param name="name">该对象的名称</param>
    public void Init(Transform tran, string name)
    {
        Register(tran, name);//注册除按钮外的交互控件
        var button = tran.GetComponent<Button>();
        if (button != null)
        {
            Bining(button, button.gameObject.name);//单纯绑定按钮控件
        }
        for (int i = 0; i < tran.childCount; i++)
        {
            Init(tran.GetChild(i), tran.GetChild(i).name);
        }
    }
    /// <summary>
    /// 非Button按钮注册
    /// </summary>
    /// <param name="tran">筛选根面板下的每个UI对象</param>
    /// <param name="name">该对象的名称</param>
    public virtual void Register(Transform tran, string name)
    {

    }
    /// <summary>
    /// Button按钮注册
    /// </summary>
    /// <param name="btn">筛选结果有Button组件的对象</param>
    /// <param name="name">该组件对象的名称</param>
    public virtual void Bining(Button btn, string name)
    {

    }
    public virtual void Start()
    {
        Init(transform, name);
    }
    /// <summary>
    /// 加载下一个界面时,调用此方法关闭上一个UI界面
    /// </summary>
    public virtual void Close()
    {
        if (UIManager.flag > 0)
        {
            Destroy(UIManager.UIPanelList[UIManager.flag - 1].gameObject);
        }
    }
}

上面脚本是所有需要动态生成界面的父类,它里面首先封装了交互性控件的注册和绑定细节,然后定义了所有界面所共用的行为,即打开、关闭等方法,

子类根据自身的特点可以选择是否重写父类的虚函数实现新的功能。

public class UIMainPanel : UIPanel
{
    private Button btn_shop;
    private Button btn_achievement;
    private Button btn_exit;
    public override void Bining(Button btn, string name)
    {
        switch (name)
        {
            case "btn_shop":
                btn.onClick.AddListener(() => xx());
                break;
            case "btn_achievement":
                btn.onClick.AddListener(() => yy());
                break;
            case "btn_exit":
                btn.onClick.AddListener(() => Close());
                break;
        }
    }
    private void xx()
    {
        Close();
        UIManager.OpendPanel<UIShopPanel>();
    }
    private void yy()
    {
        Close();
        UIManager.OpendPanel<UIAchivementPanel>();
    }
  
    public override void Close()
    {
        base.Close();
    }
}

这是继承自UIPanel的其中一个UI界面,通过它大家应该能够理解该简易框架如何运作的了吧。其他界面也和它差不太多,事实上应该还有许多可以优化的地方,

再次也仅仅只是简单的实现了一个框架该有的易用性、通用性、拓展性罢了,后面我会继续对它作进一步的优化。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值