Unity中UI框架初试探

前言
  • 我知道对于界面而言,有个框架会事半功倍
  • 我看了siki的ui框架视频,借鉴了其中的思路,自己写了一下
  • 最后当然是完美完成了。哈哈哈
  • 记录一下遇到的一些问题和解决办法
思路
  • 在Canvas上面有个UIManager 管理类负责统一的加载和销毁
  • 每个面板都有一个生命周期事件脚本
    • 生命周期 被加载—在栈顶——在下面——被关闭——被销毁
    • 当页面被点击的时候,实例化相应的面板,并加载进UIManager中的栈里面。执行元素的栈顶事件和被加载事件,对于栈顶元素,则执行在下面事件
    • 当页面被关闭的时候,就取出栈顶元素,并执行关闭事件。就是禁用
问题— 预制体无法和场景的元素产生关联
  • 由于加载和关闭函数都在UIManager类中
  • 我一开始想通过面板拖拽给面板预制体的点击事件添加方法
  • 可是Canvas在场景中,无法关联,事件总是丢失
  • 解决思路 由于每个面板都有生命周期事件,所以通过中介者模式,获得管理类的引用,调用其中的方法即可
问题二 加载顺序问题
  • 我们在实例化生成面板对象后,立马就要调用生命周期方法。
  • Start函数执行顺序在这些方法后面,会导致某些元素还没获取
  • 应该将获取元素放置在Awake方法中
问题三 点击问题
  • 每个UI面板元素都有一个canvas group组件 通过调节Alpha值和 Block RaycastHit来设定透明值和能否被射线检测到
如果一个物体被隐藏了,sendMessage是没有办法起到作用的
代码如下
  • UI管理类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum PanelType
{
    BagInfo,
    BageInfo2,
    EquipPanel,
    MainMenu,
    SinglePerson,
    SystemOption,
    UseEquip
}

public class UIManager : MonoBehaviour {

    public static UIManager instance;
    private Stack<GameObject> panelStack = new Stack<GameObject>();
    private const string path = "Panels";

    private Dictionary<string, GameObject> panelDic = new Dictionary<string, GameObject>();

    //类似于一个池子
    private Dictionary<string, GameObject> panelDic2 = new Dictionary<string, GameObject>();


    private UIManager() { } 

    private void Awake()
    {
        instance = this;
    }

    private void Start()
    {
        //获取所有页面
        GameObject[] panelObjects = Resources.LoadAll<GameObject>(path);
        foreach (var item in panelObjects)
        {
            panelDic.Add(item.name, item);
        }

        LoadPanels("MainMenu");
    }

    /// <summary>
    /// 加载页面
    /// </summary>
    /// <param name="panelName"></param>
    public void LoadPanels(string panelName)
    {
        if (!panelDic.ContainsKey(panelName)) Debug.LogError("输入的页面名字错误");

        GameObject tempTop = null;
        if (!panelDic2.ContainsKey(panelName))
        {
             tempTop = GameObject.Instantiate<GameObject>(panelDic[panelName], transform);
            panelDic2.Add(panelName, tempTop);
        }
        else
        {
            tempTop = panelDic2[panelName];
        }


        PanelLifeTime lifeControl = tempTop.GetComponent<PanelLifeTime>();

        //如果是第一次加载,就启动loading事件
        if (lifeControl.FirstLoad)
        {
            lifeControl.OnLoading();
            lifeControl.FirstLoad = false;
        }

        if (panelStack.Count != 0)
        {
            panelStack.Peek().SendMessage("OnBack"); //被遮挡
        }

        lifeControl.OnTop();
        panelStack.Push(tempTop);

       
    }

    /// <summary>
    /// 卸载页面
    /// </summary>
    /// <param name="panelName"></param>
    public void UnLoadPanels()
    {

        GameObject obj = panelStack.Pop();
        obj.SendMessage("OnClose");
        if (panelStack.Count != 0)
        {
            panelStack.Peek().SendMessage("OnTop");
        }
    }

}

  • 生命周期类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 生命周期事件脚本
/// </summary>
public class PanelLifeTime : MonoBehaviour {

    private CanvasGroup group;
    private bool firstLoad = true;


    public bool FirstLoad
    {
        get
        {
            return firstLoad;
        }

        set
        {
            firstLoad = value;
        }
    }

    private void Awake()
    {
        group = gameObject.GetComponent<CanvasGroup>();


    }

    /// <summary>
    /// 被加载
    /// </summary>
    public void OnLoading()
    {

        
    }

    /// <summary>
    /// 被遮挡
    /// </summary>
    public void OnBack()
    {
        group.blocksRaycasts = false;
        group.alpha = 0.5f;
    }

    /// <summary>
    /// 在顶部
    /// </summary>
    public void OnTop()
    {
        if (group != null)
        {
            gameObject.SetActive(true);
            group.blocksRaycasts = true;
            group.alpha = 1;
        }
        else
        {
            Debug.Log("hello problem");
        }
        
    }

    /// <summary>
    /// 关闭时
    /// </summary>
    public void OnClose()
    {
        gameObject.SetActive(false);
    }

 


    public void OnCLick(string panelName)
    {
        UIManager.instance.LoadPanels(panelName);
    }

    public void OnCloseButtonDown()
    {
        UIManager.instance.UnLoadPanels();
    }
  
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值