UGUI框架

191 篇文章 9 订阅

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

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

2, 编写UIPanelType脚本 

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

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 System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


[Serializable]  //序列化 
public class UIPanelInfo : ISerializationCallbackReceiver  /*  跟JsonUtility对应 json 解析 枚举类型  序列化和反序列化的接口*/
{ //json 解析 枚举类型 


    [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;
        Debug.Log(panelTypeString);
    }
    //序列化 从对象到文本信息
    public void OnBeforeSerialize()
    {
        throw new NotImplementedException();
    }
} 
5,然后在新建UIManager脚本 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class UIManager  {  // UIManager  UI框架的核心管理类   1,解析保存所有面板信息(PanelPathDict)
    /// <summary>
    /// 单例模式的核心
    /// 1定义一个静态的对象 在外界访问 在内结构造
    /// 2构造方法私有化
    /// </summary>
    private static UIManager _instance;

    public static UIManager Instance
    {
        get
        {
            if (_instance==null)
            {
                _instance = new UIManager(); //new的时候进行构造方法的初始化
            }
            return _instance;
        }
    }

    private Dictionary<UIPanelType, string> PanelPathDict;//存储所有的面板Prefab的路径

    [Serializable]
    class UIPanelTypeJson{

        public List<UIPanelInfo> infoList;
    }

    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);
    }
}
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==null)
            {
                _instance = new UIManager(); //new的时候进行构造方法的初始化
            }
            return _instance;
        }
    }

    private Transform canvasTranfrom;  //找到Canvas面板 吧Panel放在Canvas下面

    private Transform CanvasTranform
    {
        get {
            if (canvasTranfrom==null)
            {
                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==null)
        {
            panelDict = new Dictionary<UIPanelType, BasePanel>();


        }

        BasePanel panel;
        panelDict.TryGetValue(panelType, out panel);  //TODO 更改字典的获取方式


            if (panel==null)
            {//如果没有被实例化 就要去到他的路径去实例化他
                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上使用。

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==null)
            {
                _instance = new UIManager(); //new的时候进行构造方法的初始化
            }
            return _instance;
        }
    }

    private Transform canvasTranfrom;  //找到Canvas面板 吧Panel放在Canvas下面

    private Transform CanvasTranform
    {
        get {
            if (canvasTranfrom==null)
            {
                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==null)
        {
            panelDict = new Dictionary<UIPanelType, BasePanel>();


        }

        //BasePanel panel;
        //panelDict.TryGetValue(panelType, out panel);  //TODO 更改字典的获取方式

        BasePanel panel = panelDict.TryGet(panelType); 


            if (panel==null)
            {//如果没有被实例化 就要去到他的路径去实例化他
             //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==null)
            {
                _instance = new UIManager(); //new的时候进行构造方法的初始化
            }
            return _instance;
        }
    }

    private Transform canvasTranfrom;  //找到Canvas面板 吧Panel放在Canvas下面

    private Transform CanvasTranform
    {
        get {
            if (canvasTranfrom==null)
            {
                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==null)
        {
            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==null)
        {
            panelDict = new Dictionary<UIPanelType, BasePanel>();


        }

        //BasePanel panel;
        //panelDict.TryGetValue(panelType, out panel);  //TODO 更改字典的获取方式

        BasePanel panel = panelDict.TryGet(panelType); 


            if (panel==null)
            {//如果没有被实例化 就要去到他的路径去实例化他
             //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==null)
            {
                _instance = new UIManager(); //new的时候进行构造方法的初始化
            }
            return _instance;
        }
    }

    private Transform canvasTranfrom;  //找到Canvas面板 吧Panel放在Canvas下面

    private Transform CanvasTranform
    {
        get {
            if (canvasTranfrom==null)
            {
                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==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()
    {

    }

    /// <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)
            {//如果没有被实例化 就要去到他的路径去实例化他
             //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==null)
            {
                _instance = new UIManager(); //new的时候进行构造方法的初始化
            }
            return _instance;
        }
    }

    private Transform canvasTranfrom;  //找到Canvas面板 吧Panel放在Canvas下面

    private Transform CanvasTranform
    {
        get {
            if (canvasTranfrom==null)
            {
                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==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)
            {//如果没有被实例化 就要去到他的路径去实例化他
             //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==null)
        canvaGroup = GetComponent<CanvasGroup>();
    }

    public override void OnEnter()
    {
        if (canvaGroup == null)
            canvaGroup = GetComponent<CanvasGroup>();
        canvaGroup.alpha = 1;
        canvaGroup.blocksRaycasts = true;
    }



    /// <summary>
    /// 处理页面的关闭OnExit
    /// </summary>
    public override void OnExit()
    {
        if (canvaGroup == null)
            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 == null)
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public override void OnEnter()
    {
        if (CanvasGroup == null)
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
        CanvasGroup.alpha = 1;
        CanvasGroup.blocksRaycasts = true;
    }



    /// <summary>
    /// 移除界面
    /// </summary>
    public override void OnExit()
    {
        if (CanvasGroup == null)
        {
            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 KnapsackPanel : BasePanel {


    private CanvasGroup CanvasGroup;

    void Start()
    {
        if (CanvasGroup==null)
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
    }
    /// <summary>
    /// 
    /// </summary>
    public override void OnEnter()
    {
        if (CanvasGroup == null)
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
        CanvasGroup.alpha = 1;
        CanvasGroup.blocksRaycasts = true;
    }


    public override void OnPause() //界面暂停
    {
        CanvasGroup.blocksRaycasts = false;
    }


    public override void OnResume() //继续交互
    {
        CanvasGroup.blocksRaycasts = true;
    }


    /// <summary>
    /// 移除界面
    /// </summary>
    public override void OnExit()
    {
        if (CanvasGroup == null)
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }


        CanvasGroup.alpha = 0;
        CanvasGroup.blocksRaycasts = false;




    }




    /// <summary>
    /// 关闭按钮
    /// </summary>
	public void OnClosePanle()
    {
        UIManager.Instance.PopPanel();
    }




    public void OnItemButton()
    {
        UIManager.Instance.PushPanel(UIPanelType.ItemMessage);
    }
}


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

public class ItemMessagePanel : BasePanel {

    private CanvasGroup canvaGroup;

    void Start()
    {
        if (canvaGroup == null)
            canvaGroup = GetComponent<CanvasGroup>();
    }

    public override void OnEnter()
    {
        if (canvaGroup == null)
            canvaGroup = GetComponent<CanvasGroup>();
        canvaGroup.alpha = 1;
        canvaGroup.blocksRaycasts = true;
    }
    

    /// <summary>
    /// 处理页面的关闭OnExit
    /// </summary>
    public override void OnExit()
    {
        if (canvaGroup == null)
            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 == null)
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public override void OnEnter()
    {
        if (CanvasGroup == null)
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
        CanvasGroup.alpha = 1;
        CanvasGroup.blocksRaycasts = true;
    }



    /// <summary>
    /// 移除界面
    /// </summary>
    public override void OnExit()
    {
        if (CanvasGroup == null)
        {
            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 SkillPanel : BasePanel {

    private CanvasGroup CanvasGroup;


    void Start()
    {
        if (CanvasGroup == null)
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public override void OnEnter()
    {
        if (CanvasGroup == null)
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
        CanvasGroup.alpha = 1;
        CanvasGroup.blocksRaycasts = true;
    }



    /// <summary>
    /// 移除界面
    /// </summary>
    public override void OnExit()
    {
        if (CanvasGroup == null)
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }

        CanvasGroup.alpha = 0;
        CanvasGroup.blocksRaycasts = false;


    }


    /// <summary>
    /// 关闭按钮
    /// </summary>
	public void OnClosePanle()
    {
        UIManager.Instance.PopPanel();
    }
}


下面再添加几个DoTween动画   导入Dowteen插件

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class KnapsackPanel : BasePanel {

    private CanvasGroup CanvasGroup;


    void Start()
    {
        if (CanvasGroup==null)
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public override void OnEnter()
    {
        if (CanvasGroup == null)
        {
            CanvasGroup = this.GetComponent<CanvasGroup>();
        }
        CanvasGroup.alpha = 1;
        CanvasGroup.blocksRaycasts = true;

        Vector3 temp = transform.localPosition;
        temp.x = 600;
        transform.localPosition = temp;

        transform.DOLocalMoveX(0, 0.5f);

    }

    public override void OnPause()
    {
        CanvasGroup.blocksRaycasts = false;
    }

    public override void OnResume()
    {
        CanvasGroup.blocksRaycasts = true;
    }

    /// <summary>
    /// 移除界面
    /// </summary>
    public override void OnExit()
    {
        
       
        CanvasGroup.blocksRaycasts = false;


        //OnComplete 指播放完成以后
        transform.DOLocalMoveX(600, 0.5f).OnComplete(()=>CanvasGroup.alpha = 0);


    }


    /// <summary>
    /// 关闭按钮
    /// </summary>
	public void OnClosePanle()
    {
        UIManager.Instance.PopPanel();
    }


    public void OnItemButton()
    {
        UIManager.Instance.PushPanel(UIPanelType.ItemMessage);
    }
}


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class ItemMessagePanel : BasePanel {

    private CanvasGroup canvaGroup;

    void Start()
    {
        if (canvaGroup == null)
            canvaGroup = GetComponent<CanvasGroup>();
    }

    public override void OnEnter()
    {
        if (canvaGroup == null)
            canvaGroup = GetComponent<CanvasGroup>();
        canvaGroup.alpha = 1;
        canvaGroup.blocksRaycasts = true;
        transform.localScale = new Vector3(0,0,0);
        transform.DOScale(1, 0.5f);

    }
    

    /// <summary>
    /// 处理页面的关闭OnExit
    /// </summary>
    public override void OnExit()
    {
        if (canvaGroup == null)
            canvaGroup = GetComponent<CanvasGroup>();
        //canvaGroup.alpha = 0;
        canvaGroup.blocksRaycasts = false;
        //执行完成后
        transform.DOScale(0, 0.5f).OnComplete(()=> canvaGroup.alpha = 0);

    }
    /// <summary>
    /// 关闭按钮  调用出栈OnClosePanel
    /// </summary>
	public void OnClosePanel()
    {
        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==null)
        canvaGroup = GetComponent<CanvasGroup>();
    }

    public override void OnEnter()
    {
        if (canvaGroup == null)
            canvaGroup = GetComponent<CanvasGroup>();
        canvaGroup.alpha = 0;
        canvaGroup.blocksRaycasts = true;

        canvaGroup.DOFade(1, 0.5f);
    }



    /// <summary>
    /// 处理页面的关闭OnExit
    /// </summary>
    public override void OnExit()
    {
        if (canvaGroup == null)
            canvaGroup = GetComponent<CanvasGroup>();
        //canvaGroup.alpha = 0;
        canvaGroup.blocksRaycasts = false;
        canvaGroup.DOFade(0, 0.5f);


    }
    /// <summary>
    /// 关闭按钮  调用出栈OnClosePanel
    /// </summary>
	public void OnClosePanel()
    {
        UIManager.Instance.PopPanel();


    }
}







未完待续。。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诗远

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值