当前位置:   article > 正文

Unity UIManager框架学习笔记_unity uimanager.instance.lockscreen(0.33f);

unity uimanager.instance.lockscreen(0.33f);

Unity UIManager框架学习笔记

在这里插入图片描述

主要步骤

  1. 将所有界面做成prefab并放到resources文件夹下(后面通过resource.load读取)
  2. 编写一个json文件用于存放prefab的路径
  3. 定义脚本对json文件进行反序列,读出prefab路径并生成
  4. 定义一个BasePanel脚本,用于完成所有UI界面的通用功能
  5. 其他界面的脚本继承BasePanel脚本,完成自己的功能
  6. 定义一个UIManager单例,用于管理全部UI界面

具体实现以及代码

1. 制作界面prefab

在这里插入图片描述

2. 编写json文件存放prefab路径

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

        {
            "panelTypeString": "Task",
            "path": "UIPanel/TaskPanel"
        }
    ]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

3. 定义一个枚举,包含所有UI界面名字信息

public enum UIPanelType
{
    MainMenu,
    Task,
    Knapsack,
    Shop,
    ItemMessage
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4. 定义一个脚本,将json文件反序列化,读取UI界面prefab路径

using System;
using UnityEngine;

[Serializable]
public class UIPanelInfo: ISerializationCallbackReceiver//与JsonUtility对应
{
    [NonSerialized]
    public UIPanelType panelType;
    public string panelTypeString;
    public string path;

    //反序列化,从文本信息到对象
    public void OnAfterDeserialize()
    {
        UIPanelType type = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), panelTypeString);
        panelType=type;
    }
    
    //序列化
    public void OnBeforeSerialize()
    {
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

5. 定义BasePanel基类,声明并定义虚函数OnEnter(),OnPause(),OnResume(),OnExit(),若有其他通用功能,添加即可。后面各自UI面板的脚本继承有改动这几个接口时重写即可。

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

public class BasePanel : MonoBehaviour
{
    private CanvasGroup canvasGroup;

    public CanvasGroup CanvasGroupValue {
        get
        {
            return canvasGroup;
        }
        set
        {
            canvasGroup = value;
        }
    }

    private void Awake()
    {
        canvasGroup = GetComponent<CanvasGroup>();
    }

	//UI面板显示时调用
    public virtual void OnEnter()
    {
        canvasGroup.alpha = 1;
        canvasGroup.blocksRaycasts = true;
    }

	//暂停UI面板时调用
    public virtual void OnPause()
    {
        canvasGroup.blocksRaycasts = false;
    }

	//恢复UI面板交互时调用
    public virtual void OnResume()
    {
        canvasGroup.blocksRaycasts = true;
    }

	//隐藏UI面板时调用
    public virtual void OnExit()
    {
        canvasGroup.alpha = 0;
        canvasGroup.blocksRaycasts = false;
    }

    public virtual void OnClose()
    {
        UIManager.Instance.PopPanel();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

6. 定义UIManager脚本,设计为单例模式,方便调用。界面显示和隐藏的思想与栈相似,所以定义一个栈来完成

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

public class UIManager
{
    /// <summary>
    /// 单例模式
    /// </summary>
    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;//保存所有实例化面板身上的base组件
    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
        BasePanel panel = GetPanel(panelType);
        //调用BasePanel的OnEnter函数
        panel.OnEnter();
        //显示的面板入栈
        panelStack.Push(panel);
    }
    /// <summary>
    /// 把某个页面出栈,即移除
    /// </summary>
    public void PopPanel()
    {
        if(panelStack==null)
        {
            panelStack = new Stack<BasePanel>();
        }

        if (panelStack.Count <= 0) return;

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

        if (panelStack.Count <= 0) return;
        BasePanel topPanel = panelStack.Peek();
        topPanel.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);

        //对Direction类进行了扩展,扩展出TryGet方法,简化TryGetValue
        BasePanel panel = panelDict.TryGet(panelType);

        //如果面板还没实例化出来找不到,那么就找这个面板的路径,然后根据prefab去实例化面板
        if (panel==null)
        {
            //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;
        }
    }

    [SerializeField]
    class UIPanelTypeJson
    {
        public List<UIPanelInfo> infoList;
    }

    private void ParseUIPanelTypeJson()
    {
        panelPathDict = new Dictionary<UIPanelType, string>();

        //从Rosources中读取json文件
        TextAsset ta = Resources.Load<TextAsset>("UIPanelType");

        //将json文件反序列
        UIPanelTypeJson jsonObject = JsonUtility.FromJson<UIPanelTypeJson>(ta.text);

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149

7. 对一个类进行扩展

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 对Dictory的扩展
/// </summary>
public static class DictionaryExtension
{
    /// <summary>
    /// 尝试根据key得到value,得到了直接返回value,没有直接返回null
    /// </summary>
    /// <typeparam name="Tkey"></typeparam>
    /// <typeparam name="Tvalue"></typeparam>
    /// <param name="dict"></param>
    /// <param name=""></param>
    public static Tvalue TryGet<Tkey,Tvalue>(this Dictionary<Tkey,Tvalue> dict, Tkey key)
    {
        Tvalue value;
        dict.TryGetValue(key, out value);
        return value;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

8. 完成各自UI面板脚本的设计,界面动画效果使用DoTween插件

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);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

KnapsackPanel

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

public class KnapsackPanel : BasePanel
{
    public override void OnEnter()
    {
        CanvasGroupValue.alpha = 0f;
        CanvasGroupValue.DOFade(1, 0.5f);
    }

    public override void OnExit()
    {
        CanvasGroupValue.DOFade(0, 0.5f);
    }
    public void OnItemButtonClick()
    {
        UIManager.Instance.PushPanel(UIPanelType.ItemMessage);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

9. UIManager启动脚本

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

public class GameRoot : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        UIManager.Instance.PushPanel(UIPanelType.MainMenu);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号