Unity-UI基本搭建

UGUI框架

 本套课程是学习的Siki学院的UI框架

1,新建一个工程 在Resource文件夹下的UIPanel文件夹下 创建几个UI的Prefab。 

2, 编写UIPanelType脚本 

using UnityEngine;
using System.Collections;
using System;

public enum UIPanelType  {
    ItemMessage,
    Knapsack,
    MainMenu,
    Shop,
    Skill,
    System,
    Task
}

3,编写json存储数据   Panel的存储路径和类型 

{
"infoList":
[
{"panelTypeString":"ItemMessage",
"path":"UIPanel/ItemMessagePanel"},

{"panelTypeString":"Knapsack",
"path":"UIPanel/KnapsackPanel"},

{"panelTypeString":"MainMenu",
"path":"UIPanel/MainMenuPanel"},

{"panelTypeString":"Shop",
"path":"UIPanel/ShopPanel"},

{"panelTypeString":"Skill",
"path":"UIPanel/SkillPanel"},

{"panelTypeString":"System",
"path":"UIPanel/SystemPanel"},

{"panelTypeString":"Task",
"path":"UIPanel/TaskPanel"}

]
}

4,然后新建一个UIPaneInfo 序列化类型

using UnityEngine;
using System.Collections;
using System;

[Serializable]
public class UIPanelInfo :ISerializationCallbackReceiver {
    [NonSerialized]
    public UIPanelType panelType;
    public string panelTypeString;
    //{
    //    get
    //    {
    //        return panelType.ToString();
    //    }
    //    set
    //    {
    //        UIPanelType type =(UIPanelType)System.Enum.Parse(typeof(UIPanelType), value);
    //        panelType = type;
    //    }
    //}
    public string path;

    // 反序列化   从文本信息 到对象
    public void OnAfterDeserialize()
    {
        UIPanelType type = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), panelTypeString);
        panelType = type;
    }

    public void OnBeforeSerialize()
    {
        
    }
}

5,然后在新建UIManager脚本 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public class UIManager {

    /// 
    /// 单例模式的核心
    /// 1,定义一个静态的对象 在外界访问 在内部构造
    /// 2,构造方法私有化

    private static UIManager _instance;

    public static UIManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new UIManager();
            }
            return _instance;
        }
    }

    private Transform canvasTransform;
    private Transform CanvasTransform
    {
        get
        {
            if (canvasTransform == null)
            {
                canvasTransform = GameObject.Find("Canvas").transform;
            }
            return canvasTransform;
        }
    }
    private Dictionary<UIPanelType, string> panelPathDict;//存储所有面板Prefab的路径
    private Dictionary<UIPanelType, BasePanel> panelDict;//保存所有实例化面板的游戏物体身上的BasePanel组件
    private Stack<BasePanel> panelStack;

    private UIManager()
    {
        ParseUIPanelTypeJson();
    }

    /// <summary>
    /// 把某个页面入栈,  把某个页面显示在界面上
    /// </summary>
    public void PushPanel(UIPanelType panelType)
    {
        if (panelStack == null)
            panelStack = new Stack<BasePanel>();

        //判断一下栈里面是否有页面
        if (panelStack.Count > 0)
        {
            BasePanel topPanel = panelStack.Peek();
            topPanel.OnPause();
        }

        BasePanel panel = GetPanel(panelType);
        panel.OnEnter();
        panelStack.Push(panel);
    }
    /// <summary>
    /// 出栈 ,把页面从界面上移除
    /// </summary>
    public void PopPanel()
    {
        if (panelStack == null)
            panelStack = new Stack<BasePanel>();

        if (panelStack.Count <= 0) return;

        //关闭栈顶页面的显示
        BasePanel topPanel = panelStack.Pop();
        topPanel.OnExit();

        if (panelStack.Count <= 0) return;
        BasePanel topPanel2 = panelStack.Peek();
        topPanel2.OnResume();

    }

    /// <summary>
    /// 根据面板类型 得到实例化的面板
    /// </summary>
    /// <returns></returns>
    private BasePanel GetPanel(UIPanelType panelType)
    {
        if (panelDict == null)
        {
            panelDict = new Dictionary<UIPanelType, BasePanel>();
        }

        //BasePanel panel;
        //panelDict.TryGetValue(panelType, out panel);//TODO

        BasePanel panel = panelDict.TryGet(panelType);

        if (panel == null)
        {
            //如果找不到,那么就找这个面板的prefab的路径,然后去根据prefab去实例化面板
            //string path;
            //panelPathDict.TryGetValue(panelType, out path);
            string path = panelPathDict.TryGet(panelType);
            GameObject instPanel = GameObject.Instantiate(Resources.Load(path)) as GameObject;
            instPanel.transform.SetParent(CanvasTransform,false);
            panelDict.Add(panelType, instPanel.GetComponent<BasePanel>());
            return instPanel.GetComponent<BasePanel>();
        }
        else
        {
            return panel;
        }

    }

    [Serializable]
    class UIPanelTypeJson
    {
        public List<UIPanelInfo> infoList;
    }
    private void ParseUIPanelTypeJson()
    {
        panelPathDict = new Dictionary<UIPanelType, string>();

        TextAsset ta = Resources.Load<TextAsset>("UIPanelType");

        UIPanelTypeJson jsonObject = JsonUtility.FromJson<UIPanelTypeJson>(ta.text);

        foreach (UIPanelInfo info in jsonObject.infoList) 
        {
            //Debug.Log(info.panelType);
            panelPathDict.Add(info.panelType, info.path);
        }
    }

    /// <summary>
    /// just for test
    /// </summary>
    public void Test()
    {
        string path ;
        panelPathDict.TryGetValue(UIPanelType.Knapsack,out path);
        Debug.Log(path);
    }
}

6测试 新建一个GameRoot脚本挂载在任何物体上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class GameRoot : MonoBehaviour
{
 
    // Use this for initialization
    void Start()
    {
        UIManager.Instance.Test();
    }
 
    // Update is called once per frame
    void Update()
    {
 
    }
}

7.创建一个BasePanel Panel的公共基类 功能实现如图:


然后 新建一个BasePanel脚本  每个Panel上都要创建一个自己的脚本用来继承自BasePanel, 

8,控制UI面板的prefab的实例化创建和 管理! 在UIManager中创建新的一个字典用来存储 Panel的类型和Panel的BasePanel ,再增加一个getPanel 方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class UIManager  {  // UIManager  UI框架的核心管理类   1,解析保存所有面板信息(PanelPathDict)
     [Serializable]
    class UIPanelTypeJson{
 
        public List<UIPanelInfo> infoList;
    } 
    /// <summary>
    /// 单例模式的核心
    /// 1定义一个静态的对象 在外界访问 在内结构造
    /// 2构造方法私有化
    /// </summary>
    private static UIManager _instance;
 
    public static UIManager Instance
    {
        get
        {
            if (_instance==)
            {
                _instance = new UIManager(); //new的时候进行构造方法的初始化
            }
            return _instance;
        }
    }
 
    private Transform canvasTranfrom;  //找到Canvas面板 吧Panel放在Canvas下面
 
    private Transform CanvasTranform
    {
        get {
            if (canvasTranfrom==)
            {
                canvasTranfrom = GameObject.Find("Canvas").transform;
 
            }
            return canvasTranfrom;
        }
        
    }
 
    private Dictionary<UIPanelType, string> PanelPathDict;//存储所有的面板Prefab的路径
 
    private Dictionary<UIPanelType, BasePanel> panelDict;  //  保存所有实例化面板的游戏物体身上的BasePanel组件
 
    /// <summary>
    /// 根据面板类型  得到实例化的面板
    /// </summary>
    /// <returns></returns>
    public BasePanel GetPanel(UIPanelType panelType)
    {
        if (panelDict==)
        {
            panelDict = new Dictionary<UIPanelType, BasePanel>();
 
 
        }
 
        BasePanel panel;
        panelDict.TryGetValue(panelType, out panel);  //TODO 更改字典的获取方式
 
 
            if (panel==)
            {//如果没有被实例化 就要去到他的路径去实例化他
                string path;
                PanelPathDict.TryGetValue(panelType, out path);
 
            GameObject instancePanel =   GameObject.Instantiate( Resources.Load(path)) as  GameObject; //实例化面板
 
                instancePanel.transform.SetParent (CanvasTranform); //TODO 出现问题再解决
 
                panelDict.Add(panelType, instancePanel.GetComponent<BasePanel>());  //  添加到字典中
 
                return instancePanel.GetComponent<BasePanel>();
            }
            else
            {
                return panel;
            }
 
 
 
    }
 
 
 
    private UIManager(){
 
        ParseUIPanelTypeJson();
 
        }
    private  void ParseUIPanelTypeJson()
    {
        PanelPathDict = new Dictionary<UIPanelType, string>();
      TextAsset ta=   Resources.Load<TextAsset>("UIPanelType"); //加载json
        UIPanelTypeJson JsonObject =  JsonUtility.FromJson<UIPanelTypeJson>(ta.text);
        foreach (UIPanelInfo panel in JsonObject.infoList)
        {
            PanelPathDict.Add(panel.panelType, panel.path);  //添加到字典
        }
    }
   public void Test()
    {
        string path;
 
        PanelPathDict.TryGetValue(UIPanelType.Knapsack, out path);
 
        //Debug.Log(path);
    }
}

9创建一个字典扩展的脚本专门用来获取字典中是否存在vaule 值 如果存在返回 不存在返回null

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
/// <summary>
/// 对dictionary的扩展
/// </summary>
public static class DictionaryExtension {
    /// <summary>
    /// 尝试根据key得到value 得到的话返回vaule 没有得到直接返回null
    /// this Dictionary<TKey,TValue> dict 这个字典值要获取值的字典
    /// </summary>
    public static TValue TryGet<TKey,TValue>(this Dictionary<TKey,TValue> dict,TKey key)
    {
        TValue value;
 
        dict.TryGetValue(key,out value);
 
        return value;
    }
}

然后在UIManager上使用。

扫描二维码关注公众号,回复: 5102531 查看本文章
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class UIManager  {  // UIManager  UI框架的核心管理类   1,解析保存所有面板信息(PanelPathDict)
     [Serializable]
    class UIPanelTypeJson{
 
        public List<UIPanelInfo> infoList;
    } 
    /// <summary>
    /// 单例模式的核心
    /// 1定义一个静态的对象 在外界访问 在内结构造
    /// 2构造方法私有化
    /// </summary>
    private static UIManager _instance;
 
    public static UIManager Instance
    {
        get
        {
            if (_instance==)
            {
                _instance = new UIManager(); //new的时候进行构造方法的初始化
            }
            return _instance;
        }
    }
 
    private Transform canvasTranfrom;  //找到Canvas面板 吧Panel放在Canvas下面
 
    private Transform CanvasTranform
    {
        get {
            if (canvasTranfrom==)
            {
                canvasTranfrom = GameObject.Find("Canvas").transform;
 
            }
            return canvasTranfrom;
        }
        
    }
 
    private Dictionary<UIPanelType, string> PanelPathDict;//存储所有的面板Prefab的路径
 
    private Dictionary<UIPanelType, BasePanel> panelDict;  //  保存所有实例化面板的游戏物体身上的BasePanel组件
 
    /// <summary>
    /// 根据面板类型  得到实例化的面板
    /// </summary>
    /// <returns></returns>
    public BasePanel GetPanel(UIPanelType panelType)
    {
        if (panelDict==)
        {
            panelDict = new Dictionary<UIPanelType, BasePanel>();
 
 
        }
 
        //BasePanel panel;
        //panelDict.TryGetValue(panelType, out panel);  //TODO 更改字典的获取方式
 
        BasePanel panel = panelDict.TryGet(panelType); 
 
 
            if (panel==)
            {//如果没有被实例化 就要去到他的路径去实例化他
             //string path;
             //PanelPathDict.TryGetValue(panelType, out path);
 
            string path = PanelPathDict.TryGet(panelType);
 
            GameObject instancePanel =   GameObject.Instantiate( Resources.Load(path)) as  GameObject; //实例化面板
 
                instancePanel.transform.SetParent (CanvasTranform); //TODO 出现问题再解决
 
                panelDict.Add(panelType, instancePanel.GetComponent<BasePanel>());  //  添加到字典中
 
                return instancePanel.GetComponent<BasePanel>();
            }
            else
            {
                return panel;
            }
 
 
 
    }
 
 
 
    private UIManager(){
 
        ParseUIPanelTypeJson();
 
        }
    private  void ParseUIPanelTypeJson()
    {
        PanelPathDict = new Dictionary<UIPanelType, string>();
      TextAsset ta=   Resources.Load<TextAsset>("UIPanelType"); //加载json
        UIPanelTypeJson JsonObject =  JsonUtility.FromJson<UIPanelTypeJson>(ta.text);
        foreach (UIPanelInfo panel in JsonObject.infoList)
        {
            PanelPathDict.Add(panel.panelType, panel.path);  //添加到字典
        }
    }
   public void Test()
    {
        string path;
 
        PanelPathDict.TryGetValue(UIPanelType.Knapsack, out path);
 
        //Debug.Log(path);
    }
}

10,分析界面的存储栈

现在的UIManager 又多了两个个功能  , 有三个功能 1,解析保存所有控制面板信息(PanelPathDic) 2,创建保存所有面板的事例( PanelDic),3,管理保存所有显示的面板(显示页面的容器栈 ,后进先出)如图:

11,创建Stack存储界面面板

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class UIManager  {  // UIManager  UI框架的核心管理类   1,解析保存所有面板信息(PanelPathDict)
     [Serializable]
    class UIPanelTypeJson{
 
        public List<UIPanelInfo> infoList;
    } 
    /// <summary>
    /// 单例模式的核心
    /// 1定义一个静态的对象 在外界访问 在内结构造
    /// 2构造方法私有化
    /// </summary>
    private static UIManager _instance;
 
    public static UIManager Instance
    {
        get
        {
            if (_instance==)
            {
                _instance = new UIManager(); //new的时候进行构造方法的初始化
            }
            return _instance;
        }
    }
 
    private Transform canvasTranfrom;  //找到Canvas面板 吧Panel放在Canvas下面
 
    private Transform CanvasTranform
    {
        get {
            if (canvasTranfrom==)
            {
                canvasTranfrom = GameObject.Find("Canvas").transform;
 
            }
            return canvasTranfrom;
        }
        
    }
 
    private Dictionary<UIPanelType, string> PanelPathDict;//存储所有的面板Prefab的路径
 
    private Dictionary<UIPanelType, BasePanel> panelDict;  //  保存所有实例化面板的游戏物体身上的BasePanel组件
 
    private Stack<BasePanel> panelStack;  //栈
 
    /// <summary>
    /// 把某个界面入栈,吧某个界面显示在界面上
    /// </summary>
    public void PushPanel(UIPanelType panelType) 
    {
        if (panelStack==)
        {
            panelStack = new Stack<BasePanel>();
        }
 
        BasePanel panel = GetPanel(panelType);
 
        panelStack.Push(panel);
 
    }
    /// <summary>
    /// 出栈   吧页面从界面移除
    /// </summary>
    public  void PopPanel()
    {
 
    }
 
    /// <summary>
    /// 根据面板类型  得到实例化的面板
    /// </summary>
    /// <returns></returns>
    private BasePanel GetPanel(UIPanelType panelType)
    {
        if (panelDict==)
        {
            panelDict = new Dictionary<UIPanelType, BasePanel>();
 
 
        }
 
        //BasePanel panel;
        //panelDict.TryGetValue(panelType, out panel);  //TODO 更改字典的获取方式
 
        BasePanel panel = panelDict.TryGet(panelType); 
 
 
            if (panel==)
            {//如果没有被实例化 就要去到他的路径去实例化他
             //string path;
             //PanelPathDict.TryGetValue(panelType, out path);
 
            string path = PanelPathDict.TryGet(panelType);
 
            GameObject instancePanel =   GameObject.Instantiate( Resources.Load(path)) as  GameObject; //实例化面板
 
                instancePanel.transform.SetParent (CanvasTranform,false); 
 
                panelDict.Add(panelType, instancePanel.GetComponent<BasePanel>());  //  添加到字典中
 
                return instancePanel.GetComponent<BasePanel>();
            }
            else
            {
                return panel;
            }
 
 
 
    }
 
 
 
    private UIManager(){
 
        ParseUIPanelTypeJson();
 
        }
    private  void ParseUIPanelTypeJson()
    {
        PanelPathDict = new Dictionary<UIPanelType, string>();
      TextAsset ta=   Resources.Load<TextAsset>("UIPanelType"); //加载json
        UIPanelTypeJson JsonObject =  JsonUtility.FromJson<UIPanelTypeJson>(ta.text);
        foreach (UIPanelInfo panel in JsonObject.infoList)
        {
            PanelPathDict.Add(panel.panelType, panel.path);  //添加到字典
        }
    }
   public void Test()
    {
        string path;
 
        PanelPathDict.TryGetValue(UIPanelType.Knapsack, out path);
 
        //Debug.Log(path);
    }
}


然后在GameRoot 里面测试 入栈

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class GameRoot : MonoBehaviour  //负责启动整个UI框架
{
 
    // Use this for initialization
    void Start()
    {
        UIManager.Instance.PushPanel(UIPanelType.MainMenu);
 
       // UIManager.Instance.Test();
    }
 
    // Update is called once per frame
    void Update()
    {
 
    }
}

现在能加载出来哦 就是没问题!

12,现在要做 MainMenuPanel的点击事件,背包,系统 ,技能,商店,  修改

出栈的操作

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class MainMenuPanel : BasePanel {
    public  void OnPushPanel(string  panelTypeString)
    {
      UIPanelType PanelType = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), panelTypeString);
 
        UIManager.Instance.PushPanel(PanelType);
    }
}
 

13,我们这节课设置页面的几种状态 如图示

把这四个方法在下BasePanel里面 让集成他的子类重写此方法

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()
    {
 
    }
}


14  开发OnEnter和OnPause的调用 

然后在UIManager应用在 入栈 之前 代码实现如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class UIManager  {  // UIManager  UI框架的核心管理类   1,解析保存所有面板信息(PanelPathDict)
     [Serializable]
    class UIPanelTypeJson{
 
        public List<UIPanelInfo> infoList;
    } 
    /// <summary>
    /// 单例模式的核心
    /// 1定义一个静态的对象 在外界访问 在内结构造
    /// 2构造方法私有化
    /// </summary>
    private static UIManager _instance;
 
    public static UIManager Instance
    {
        get
        {
            if (_instance==)
            {
                _instance = new UIManager(); //new的时候进行构造方法的初始化
            }
            return _instance;
        }
    }
 
    private Transform canvasTranfrom;  //找到Canvas面板 吧Panel放在Canvas下面
 
    private Transform CanvasTranform
    {
        get {
            if (canvasTranfrom==)
            {
                canvasTranfrom = GameObject.Find("Canvas").transform;
 
            }
            return canvasTranfrom;
        }
        
    }
 
    private Dictionary<UIPanelType, string> PanelPathDict;//存储所有的面板Prefab的路径
 
    private Dictionary<UIPanelType, BasePanel> panelDict;  //  保存所有实例化面板的游戏物体身上的BasePanel组件
 
    private Stack<BasePanel> panelStack;  //栈
 
    /// <summary>
    /// 把某个界面入栈,吧某个界面显示在界面上
    /// </summary>
    public void PushPanel(UIPanelType panelType) 
    {
        if (panelStack==)
        {
            panelStack = new Stack<BasePanel>();
        }
 
        //添加之前 判断是否有页面
        if (panelStack.Count>0)
        {
            BasePanel topPanel = panelStack.Peek();
            topPanel.OnPause();
        }
 
        BasePanel panel = GetPanel(panelType);
 
        panel.OnEnter();
         
        panelStack.Push(panel);
 
    }
    /// <summary>
    /// 出栈   吧页面从界面移除
    /// </summary>
    public  void PopPanel()
    {
 
    }
 
    /// <summary>
    /// 根据面板类型  得到实例化的面板
    /// </summary>
    /// <returns></returns>
    private BasePanel GetPanel(UIPanelType panelType)
    {
        if (panelDict==)
        {
            panelDict = new Dictionary<UIPanelType, BasePanel>();
 
 
        }
 
        //BasePanel panel;
        //panelDict.TryGetValue(panelType, out panel);  //TODO 更改字典的获取方式
 
        BasePanel panel = panelDict.TryGet(panelType); 
 
 
            if (panel==)
            {//如果没有被实例化 就要去到他的路径去实例化他
             //string path;
             //PanelPathDict.TryGetValue(panelType, out path);
 
            string path = PanelPathDict.TryGet(panelType);
 
            GameObject instancePanel =   GameObject.Instantiate( Resources.Load(path)) as  GameObject; //实例化面板
 
                instancePanel.transform.SetParent (CanvasTranform,false); 
 
                panelDict.Add(panelType, instancePanel.GetComponent<BasePanel>());  //  添加到字典中
 
                return instancePanel.GetComponent<BasePanel>();
            }
            else
            {
                return panel;
            }
    }
 
    private UIManager(){
 
        ParseUIPanelTypeJson();
 
        }
    private  void ParseUIPanelTypeJson()
    {
        PanelPathDict = new Dictionary<UIPanelType, string>();
      TextAsset ta=   Resources.Load<TextAsset>("UIPanelType"); //加载json
        UIPanelTypeJson JsonObject =  JsonUtility.FromJson<UIPanelTypeJson>(ta.text);
        foreach (UIPanelInfo panel in JsonObject.infoList)
        {
            PanelPathDict.Add(panel.panelType, panel.path);  //添加到字典
        }
    }
   public void Test()
    {
        string path;
 
        PanelPathDict.TryGetValue(UIPanelType.Knapsack, out path);
 
        //Debug.Log(path);
    }
}


15 处理菜单的OnPause暂停

先设置MainMenu实现暂停 暂停前先给mainmenu添加一个CanvasGroup 组件  然后点击Apply

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class MainMenuPanel : BasePanel {
 
    private CanvasGroup canvasGroup;
 
    void Start()
    {
        canvasGroup = this.GetComponent<CanvasGroup>();
    }
    public override void OnPause()
    {
 
        canvasGroup.blocksRaycasts = false; //当弹出新的面板的时候 让主菜单面板不再和鼠标进行交互
 
    }
 
 
    public  void OnPushPanel(string  panelTypeString)
    {
      UIPanelType PanelType = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), panelTypeString);
 
        UIManager.Instance.PushPanel(PanelType);
    }
}
16,控制界面的出栈 界面的隐藏和关闭。

我们先解决出栈问题:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class UIManager  {  // UIManager  UI框架的核心管理类   1,解析保存所有面板信息(PanelPathDict)
     [Serializable]
    class UIPanelTypeJson{
 
        public List<UIPanelInfo> infoList;
    } 
    /// <summary>
    /// 单例模式的核心
    /// 1定义一个静态的对象 在外界访问 在内结构造
    /// 2构造方法私有化
    /// </summary>
    private static UIManager _instance;
 
    public static UIManager Instance
    {
        get
        {
            if (_instance==)
            {
                _instance = new UIManager(); //new的时候进行构造方法的初始化
            }
            return _instance;
        }
    }
 
    private Transform canvasTranfrom;  //找到Canvas面板 吧Panel放在Canvas下面
 
    private Transform CanvasTranform
    {
        get {
            if (canvasTranfrom==)
            {
                canvasTranfrom = GameObject.Find("Canvas").transform;
 
            }
            return canvasTranfrom;
        }
        
    }
 
    private Dictionary<UIPanelType, string> PanelPathDict;//存储所有的面板Prefab的路径
 
    private Dictionary<UIPanelType, BasePanel> panelDict;  //  保存所有实例化面板的游戏物体身上的BasePanel组件
 
    private Stack<BasePanel> panelStack;  //栈
 
    /// <summary>
    /// 把某个界面入栈,吧某个界面显示在界面上
    /// </summary>
    public void PushPanel(UIPanelType panelType) 
    {
        if (panelStack==)
        {
            panelStack = new Stack<BasePanel>();
        }
 
        //添加之前 判断是否有页面
        if (panelStack.Count>0)
        {
            BasePanel topPanel = panelStack.Peek();
            topPanel.OnPause();
        }
 
        BasePanel panel = GetPanel(panelType);
 
        panel.OnEnter();
         
        panelStack.Push(panel);
 
    }
    /// <summary>
    /// 出栈   吧页面从界面移除
    /// </summary>
    public  void PopPanel()
    {
        if (panelStack == )
        {
            panelStack = new Stack<BasePanel>();
        }
        if (panelStack.Count <= 0) return;
 
        //关闭栈顶页面的显示
        BasePanel topPanel = panelStack.Pop();
        topPanel.OnExit();
 
        // 如果下面有页面 就让他显示出来 继续交互
        if (panelStack.Count <= 0) return;
 
        BasePanel topPanel2 = panelStack.Peek();
        topPanel2.OnResume(); //继续交互
    }
 
    /// <summary>
    /// 根据面板类型  得到实例化的面板
    /// </summary>
    /// <returns></returns>
    private BasePanel GetPanel(UIPanelType panelType)
    {
        if (panelDict==)
        {
            panelDict = new Dictionary<UIPanelType, BasePanel>();
 
 
        }
 
        //BasePanel panel;
        //panelDict.TryGetValue(panelType, out panel);  //TODO 更改字典的获取方式
 
        BasePanel panel = panelDict.TryGet(panelType); 
 
 
            if (panel==)
            {//如果没有被实例化 就要去到他的路径去实例化他
             //string path;
             //PanelPathDict.TryGetValue(panelType, out path);
 
            string path = PanelPathDict.TryGet(panelType);
 
            GameObject instancePanel =   GameObject.Instantiate( Resources.Load(path)) as  GameObject; //实例化面板
 
                instancePanel.transform.SetParent (CanvasTranform,false); 
 
                panelDict.Add(panelType, instancePanel.GetComponent<BasePanel>());  //  添加到字典中
 
                return instancePanel.GetComponent<BasePanel>();
            }
            else
            {
                return panel;
            }
    }
 
    private UIManager(){
 
        ParseUIPanelTypeJson();
 
        }
    private  void ParseUIPanelTypeJson()
    {
        PanelPathDict = new Dictionary<UIPanelType, string>();
      TextAsset ta=   Resources.Load<TextAsset>("UIPanelType"); //加载json
        UIPanelTypeJson JsonObject =  JsonUtility.FromJson<UIPanelTypeJson>(ta.text);
        foreach (UIPanelInfo panel in JsonObject.infoList)
        {
            PanelPathDict.Add(panel.panelType, panel.path);  //添加到字典
        }
    }
   public void Test()
    {
        string path;
 
        PanelPathDict.TryGetValue(UIPanelType.Knapsack, out path);
 
        //Debug.Log(path);
    }
}


然后我们拿Task 举例子  吧Task拖到Canvas下面   先把Task面板 添加一个canvasGroup组件 Apply一下 打开 TaskPanle脚本 写OnClosePanel 方法进行出栈 ,然后重写关闭按钮  调用出栈OnClosePanel  ,  处理页面的关闭OnExit ,OnEnter ,和mainMenu 的 OnResume 方法 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class TaskPanel : BasePanel {
 
    private CanvasGroup canvaGroup;
 
    void Start()
    {
        if (canvaGroup==)
        canvaGroup = GetComponent<CanvasGroup>();
    }
 
    public override void OnEnter()
    {
        if (canvaGroup == )
            canvaGroup = GetComponent<CanvasGroup>();
        canvaGroup.alpha = 1;
        canvaGroup.blocksRaycasts = true;
    }
 
 
 
    /// <summary>
    /// 处理页面的关闭OnExit
    /// </summary>
    public override void OnExit()
    {
        if (canvaGroup == )
            canvaGroup = GetComponent<CanvasGroup>();
        canvaGroup.alpha = 0;
        canvaGroup.blocksRaycasts = false;
 
    }
    /// <summary>
    /// 关闭按钮  调用出栈OnClosePanel
    /// </summary>
	public void OnClosePanel()
    {
        UIManager.Instance.PopPanel();
 
 
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class MainMenuPanel : BasePanel {
 
    private CanvasGroup canvasGroup;
 
    void Start()
    {
        canvasGroup = this.GetComponent<CanvasGroup>();
    }
 
    public override void OnPause()
    {
 
        canvasGroup.blocksRaycasts = false; //当弹出新的面板的时候 让主菜单面板不再和鼠标进行交互
 
    }
    /// <summary>
    /// 继续交互
    /// </summary>
    public override void OnResume()
    {
 
        canvasGroup.blocksRaycasts = true;
    }
 
    public  void OnPushPanel(string  panelTypeString)
    {
      UIPanelType PanelType = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), panelTypeString);
 
        UIManager.Instance.PushPanel(PanelType);
    }
}

17,控制面板之间的跳转

然后重新把剩下的面板跳转都实现了。 都要添加CanvasGroup

系统设置

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class SystemPanel : BasePanel {
 
    private CanvasGroup CanvasGroup;
 
 
    void Start()
    {
        if (CanvasGroup == )
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
    }
 
    /// <summary>
    /// 
    /// </summary>
    public override void OnEnter()
    {
        if (CanvasGroup == )
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
        CanvasGroup.alpha = 1;
        CanvasGroup.blocksRaycasts = true;
    }
 
 
 
    /// <summary>
    /// 移除界面
    /// </summary>
    public override void OnExit()
    {
        if (CanvasGroup == )
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
 
        CanvasGroup.alpha = 0;
        CanvasGroup.blocksRaycasts = false;
 
 
    }
 
 
    /// <summary>
    /// 关闭按钮
    /// </summary>
	public void OnClosePanle()
    {
        UIManager.Instance.PopPanel();
    }
}

背包 

背包里面还有一个ItemMessagePanel  点击里面的Item后就不能进行背包的点击了 在原来的基础上 又要重写暂停和和继续交互方法,然后再注册 ItemMessagePanel的关闭方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class SystemPanel : BasePanel {
 
    private CanvasGroup CanvasGroup;
 
 
    void Start()
    {
        if (CanvasGroup == )
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
    }
 
    /// <summary>
    /// 
    /// </summary>
    public override void OnEnter()
    {
        if (CanvasGroup == )
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
        CanvasGroup.alpha = 1;
        CanvasGroup.blocksRaycasts = true;
    }
 
 
 
    /// <summary>
    /// 移除界面
    /// </summary>
    public override void OnExit()
    {
        if (CanvasGroup == )
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
 
        CanvasGroup.alpha = 0;
        CanvasGroup.blocksRaycasts = false;
 
 
    }
 
 
    /// <summary>
    /// 关闭按钮
    /// </summary>
	public void OnClosePanle()
    {
        UIManager.Instance.PopPanel();
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ItemMessagePanel : BasePanel {
 
    private CanvasGroup canvaGroup;
 
    void Start()
    {
        if (canvaGroup == )
            canvaGroup = GetComponent<CanvasGroup>();
    }
 
    public override void OnEnter()
    {
        if (canvaGroup == )
            canvaGroup = GetComponent<CanvasGroup>();
        canvaGroup.alpha = 1;
        canvaGroup.blocksRaycasts = true;
    }
    
 
    /// <summary>
    /// 处理页面的关闭OnExit
    /// </summary>
    public override void OnExit()
    {
        if (canvaGroup == )
            canvaGroup = GetComponent<CanvasGroup>();
        canvaGroup.alpha = 0;
        canvaGroup.blocksRaycasts = false;
 
    }
    /// <summary>
    /// 关闭按钮  调用出栈OnClosePanel
    /// </summary>
	public void OnClosePanel()
    {
        UIManager.Instance.PopPanel();
 
 
    }
}

商城

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ShopPanel : BasePanel {
    private CanvasGroup CanvasGroup;
 
 
    void Start()
    {
        if (CanvasGroup == )
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
    }
 
    /// <summary>
    /// 
    /// </summary>
    public override void OnEnter()
    {
        if (CanvasGroup == )
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
        CanvasGroup.alpha = 1;
        CanvasGroup.blocksRaycasts = true;
    }
 
 
 
    /// <summary>
    /// 移除界面
    /// </summary>
    public override void OnExit()
    {
        if (CanvasGroup == )
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
 
        CanvasGroup.alpha = 0;
        CanvasGroup.blocksRaycasts = false;
 
 
    }
 
 
    /// <summary>
    /// 关闭按钮
    /// </summary>
	public void OnClosePanle()
    {
        UIManager.Instance.PopPanel();
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
 
public class TaskPanel : BasePanel {
 
    private CanvasGroup canvaGroup;
 
    void Start()
    {
        if (canvaGroup==)
        canvaGroup = GetComponent<CanvasGroup>();
    }
 
    public override void OnEnter()
    {
        if (canvaGroup == )
            canvaGroup = GetComponent<CanvasGroup>();
        canvaGroup.alpha = 0;
        canvaGroup.blocksRaycasts = true;
 
        canvaGroup.DOFade(1, 0.5f);
    }
 
 
 
    /// <summary>
    /// 处理页面的关闭OnExit
    /// </summary>
    public override void OnExit()
    {
        if (canvaGroup == )
            canvaGroup = GetComponent<CanvasGroup>();
        //canvaGroup.alpha = 0;
        canvaGroup.blocksRaycasts = false;
        canvaGroup.DOFade(0, 0.5f);
 
 
    }
    /// <summary>
    /// 关闭按钮  调用出栈OnClosePanel
    /// </summary>
	public void OnClosePanel()
    {
        UIManager.Instance.PopPanel();
 
 
    }
}

猜你喜欢

转载自blog.csdn.net/qq_31741481/article/details/85616976
今日推荐