U3D设计模式之UI框架

  每个游戏的有UI,合理的UI管理可以更加节省游戏资源。本篇是对UI框架的总结。

  UI框架就是把所有的UI做成Prefab存进Json文件中,等触发的时候再通过点击事件实例化出相应的UI预制体。这样做的好处是,游戏面板上什么都没有,用到什么就生成什么,为了避免重复生成,采用单例的方式来实现。

  一、搭建UI界面。

 

 

 二、写代码:

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
//转化枚举信息给json解析提供值
[Serializable]//序列化信息(把对象转化为文本,转换为二进制)
public class UIPanelInfo : ISerializationCallbackReceiver//序列化接口
{
    [NonSerialized]
    public UIPanelType type;//定义枚举
    public string PanelTypeString;
    public string path;//json解析时要把该类信息都传递过去,所以path信息也要获取

    public void OnAfterDeserialize()//反序列化之后执行的内容就是文本变对象
    {
           UIPanelType typeinfo=(UIPanelType)Enum.Parse(typeof(UIPanelType),PanelTypeString);
           type = typeinfo;
    }
    public void OnBeforeSerialize()
    {
       
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TaskPanel: BasePanel
{
    private CanvasGroup cg;
    // Use this for initialization
    void Start () {
        if (cg == null)
        {
            cg = GetComponent<CanvasGroup>();
        }
        cg = GetComponent<CanvasGroup>();
    }
    //重写显示界面
    public override void OnEnter()
    {
        if (cg==null)
        {
            cg = GetComponent<CanvasGroup>();
        }
        cg.blocksRaycasts = true;
        cg.alpha = 1;    
    }
    public void ClosePanel() {

        UIManager.Instance.PopPanel();
    }
    public override void OnExit()
    {
        cg.blocksRaycasts = false;
        cg.alpha = 0;
    }
}
--------------------------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BasePanel : MonoBehaviour
{
    /// <summary>
    /// 显示界面
    /// </summary>
    public virtual void OnEnter() { }
    /// <summary>
    /// 暂停界面
    /// </summary>
    public virtual void OnPause() { }
    /// <summary>
    /// 继续界面(恢复交互)
    /// </summary>
    public virtual void OnResume() { }
    /// <summary>
    /// 退出界面(移除)
    /// </summary>
    public virtual void OnExit() { }
}
--------------------------------------------------------------------------------
 //定义一个栈(Stack)
    Stack<BasePanel> stack;
    /// <summary>
    /// 把某个界面进栈,用于显示当前的界面
    /// </summary>
    public void PushPanel(UIPanelType panelType)
    {
        if (stack==null)
        {
            stack = new Stack<BasePanel>();
        }
        if (stack.Count>0)
        {
           Debug.Log(1231456);
          BasePanel basePanel=  stack.Peek();//检测里面最上面的界面,然后去暂停
          basePanel.OnPause();
        }
        Debug.Log(6666);
        BasePanel bp  = GetPanel(panelType);
          bp.OnEnter();
         stack.Push(bp);

    }
    /// <summary>
    /// 出栈就是把这个界面移除
    /// </summary>
    public void PopPanel()
    {
        Debug.Log("看一看");
        if (stack == null)
        {
            stack = new Stack<BasePanel>();
        }
        if (stack.Count <= 0) return;
        //关闭栈顶的界面(peek的东西)
         BasePanel bp= stack.Pop();//出栈//关闭子界面(预示着原来的老界面要继续激活)
         bp.OnExit();
        if (stack.Count <= 0) return;
         BasePanel basePanel= stack.Peek();//老界面(之前暂停的界面)拿出来激活
         basePanel.OnResume();//可以继续交互了
    }
}
--------------------------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class MainmenuPanel : BasePanel
{
    private CanvasGroup cg;


void Start () {
        if (cg == null)
        {
            cg = GetComponent<CanvasGroup>();
        }
        cg = GetComponent<CanvasGroup>();
}
    //告诉UImanger我想要哪个界面,你就给我生成或者直接拿给我
    public void OnClickType(string type)
    {
       UIPanelType panelType= (UIPanelType)Enum.Parse(typeof(UIPanelType),type);
       UIManager.Instance.PushPanel(panelType);

        Debug.Log(type);
    }
    public override void OnPause()
    {
        if (cg == null)
        {
            cg = GetComponent<CanvasGroup>();
        }
        cg.blocksRaycasts = false;
        Debug.Log(888);
    }
    public override void OnResume()
    {
        base.OnResume();
        cg.blocksRaycasts = true;
    }
  

}
--------------------------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class KnapsackPanel : BasePanel
{

private CanvasGroup cg;
    // Use this for initialization
    void Start()
    {
        if (cg == null)
        {
            cg = GetComponent<CanvasGroup>();
        }
      
    }
    //重写显示界面
    public override void OnEnter()
    {
        if (cg == null)
        {
            cg = GetComponent<CanvasGroup>();
        }
        cg.blocksRaycasts = true;
        cg.alpha = 1;
    }
    public override void OnPause()
    {
        Debug.Log("调用");
        cg.blocksRaycasts = false;

    }
    public override void OnResume()
    {
        cg.blocksRaycasts = true;
    }
    public void ClosePanel()
    {
        UIManager.Instance.PopPanel();
    }
    public override void OnExit()
    {
        cg.blocksRaycasts = false;
        cg.alpha = 0;
    }
    public void OnClickItem() {
        UIManager.Instance.PushPanel(UIPanelType.ItemMessage);
    }
}

遇到的坑:

Json文件虽然可以读出来,但是无法在面板上显示,是因为Json文件里的变量名称要和代码里的变量名称一致,不然无法实别到。

posted @ 2018-01-24 20:53  薛小爽  阅读(989)  评论(0编辑  收藏  举报