zoukankan      html  css  js  c++  java
  • UI框架搭建DAY1

    分析:UI框架主要是为了用户(使用框架的程序猿)更快捷、方便地开发UI,UI框架的好处还在于解耦,使得程序更具有灵活性。

    UI框架的核心是窗口的管理,窗口管理的主要任务就是显示窗口和关闭窗口。

    因为窗口的类型多样,比如弹出式窗口,固定位置窗口,隐藏其他窗口(打开这个窗口会覆盖整个屏幕),模态窗口等等。

    这里我目前把窗口分为三大类型:普通窗口、弹出式窗口、隐藏其他窗口,而位置固定、是否模态作为窗口的属性。

    1.为了更易于复用和拓展,我设计了一个基类BasePanel, NormalPanel, PopupPanel, HiderOtherPanel都由此基类派生。

    BasePanel封装了3个重要方法:Open(), Close(), Freeze()。

    2.巧妇难为无米之炊,要显示这些窗体首先要制作这些窗体的预制体,然后加载。为此,我又设计了一个核心类PanelManager。

    PanelManager主要负责窗体的创建和销毁(隐藏),核心方法CreatePanel()。另外使用了对象池技术,缓存窗体。

    3.要动态加载窗体,必须获得窗体资源的路径,为此我设计了一个SysDefine类,此文件用于定义一些预制体路径常量,节点(Inspector面板中的物体位置)常量。(后期重构时打算用Json文件配置)。加载资源的类ResourceManager。

    4.此外,我还设计了一个帮助类Helper,目前实现的功能仅仅是自动化设置窗体节点的父节点。

    下面,展示我今天下午的成果。

     1 using UnityEngine;
     2 
     3 public class BasePanel : MonoBehaviour
     4 {
     5     //窗体类型
     6    public EPanelType panelType;
     7     //是否是模态窗口
     8     public bool isModal;
     9     //是否是固定位置窗口
    10     public bool isFixed;
    11     //透明度
    12     ETransparencyLevel transLevel;
    13 
    14 
    15     //初始化
    16     private void Awake()
    17     {
    18         panelType = EPanelType.Normal;
    19         isModal = true;
    20         isFixed = false;
    21         transLevel = ETransparencyLevel.Opaque;
    22     }
    23 
    24     private void Start()
    25     {
    26         //自动设置物体的父节点
    27         Helper.GetInstance().SetParent(gameObject);
    28      
    29     }
    30 
    31     //打开窗口
    32     public void Open()
    33     {
    34         gameObject.SetActive(true);
    35     }
    36     //关闭窗口
    37     public void Close()
    38     {
    39         gameObject.SetActive(false);
    40     }
    41     //冻结窗口
    42    public void Freeze()
    43     {
    44         //TO DO
    45     }
    46 }
     1 using System.Collections.Generic;
     2 using UnityEngine;
     3 public class PanelManager
     4 {
     5     //本类实例
     6     private static PanelManager _instance;
     7     //存储面板名字和对应的路径字典
     8     public static Dictionary<string, string> dictPanelPath;
     9     //存储已显示的面板字典
    10     public static Dictionary<string, BasePanel> dictCurPanel;
    11     //存储已隐藏的面板字典
    12     public static Dictionary<string, BasePanel> dictHidePanel;
    13     //存储Popup类型面板的字典
    14     public static Dictionary<string, Stack<BasePanel>> dictPopupPanel;
    15 
    16     //单例模式
    17     private PanelManager() { }
    18     public static PanelManager GetInstance()
    19     {
    20         if(_instance == null)
    21         {
    22             _instance = new PanelManager();
    23 
    24             InitProperties();
    25         }
    26         return _instance;
    27     }
    28     //初始化字段
    29     private static void InitProperties()
    30     {
    31         dictPanelPath = new Dictionary<string, string>();
    32         dictCurPanel = new Dictionary<string, BasePanel>();
    33         dictHidePanel = new Dictionary<string, BasePanel>();
    34         dictPopupPanel = new Dictionary<string, Stack<BasePanel>>();
    35     }
    36     /// <summary>
    37     /// 创建一个面板
    38     /// 先检查dictHidePanel集合里是否存在此面板,有则取出显示并加入dictCurPanel集合
    39     /// 没有,则创建一个,然后加如dictCurPanel集合。
    40     /// </summary>
    41     /// <param name="panelName">要创建的面板的名字</param>
    42     /// <returns></returns>
    43     public BasePanel CreatePanel(string panelName)
    44     {
    45         BasePanel basePanel = null;        
    46         dictHidePanel.TryGetValue(panelName, out basePanel);
    47         if(basePanel != null)
    48         {
    49             return basePanel;
    50         }
    51         else
    52         {
    53             //创建面板
    54             GameObject go = ResourceManager.GetInstance().LoadAsset<GameObject>(panelName);
    55             if(go != null)
    56             {
    57                 basePanel = go.GetComponent<BasePanel>();
    58                 if(basePanel != null)
    59                 {
    60                     //添加到正在显示的面板集合
    61                     dictCurPanel.Add(panelName, basePanel);
    62                 }
    63                 else
    64                 {
    65                     Debug.LogError(GetType()+"你可能忘记挂在了BasePanel类型的脚本");
    66                 }
    67                 return basePanel;
    68             }
    69             else
    70             {
    71                 Debug.Log(GetType()+"panelName可能不存在");
    72 
    73             }
    74         }
    75         return null;
    76     }
    77 
    78 }
     1 using UnityEngine;
     2 
     3 public class ResourceManager
     4 {
     5     private static ResourceManager _instance;
     6     public static ResourceManager GetInstance()
     7     {
     8         if (_instance == null)
     9         {
    10             _instance = new ResourceManager();
    11         }
    12         return _instance;
    13     }
    14     private ResourceManager() { }
    15 
    16     public T LoadAsset<T>(string path)where T:Object
    17     {
    18         Object o = Resources.Load(path);
    19         //实例化
    20         GameObject go = GameObject.Instantiate(o) as GameObject;
    21       
    22         return go as T;
    23     }
    24 
    25 }
     1 public enum ETransparencyLevel
     2 {
     3     Opaque,                                 //不透明
     4     Translucence,                           //半透明的
     5     Transparent,                            //透明的
     6 }
     7 public enum EPanelType
     8 {
     9     Normal,
    10     Popup,
    11     HideOther
    12 }
    13 public  class PrefabPathStr
    14 {
    15     public const string uiRootPath = @"Prefabs/UIRoot";
    16     public const string logOnPanelPath = @"Prefabs/LogOnPanel";
    17 }
    18 public class NodePathStr
    19 {
    20     public const string normalPath = @"UIRoot/Normal";
    21     public const string popupPath = @"UIRoot/Popup";
    22     public const string hiderOtherPath = @"UIRoot/HideOther";
    23 }
    24 
    25 
    26 
    27 public class SysDefine
    28 {
    29 }
     1 using UnityEngine;
     2 
     3 public class Helper
     4 {
     5     private static Helper _instance = null;                                    //本类实;
     6     private static Transform normal;                                   //normal 节点
     7     private static Transform popup;                                    //popup 节点
     8     private static Transform hiderOther;                               //hiderOther 节点
     9     
    10 
    11     //单利模式
    12     public static Helper GetInstance()
    13     {
    14         if(_instance == null)
    15         {                                                               //本类实例化时,初始化节点字段
    16             normal = GameObject.Find(NodePathStr.normalPath).transform;
    17             popup = GameObject.Find(NodePathStr.popupPath).transform;
    18             hiderOther = GameObject.Find(NodePathStr.hiderOtherPath).transform;
    19             _instance = new Helper();
    20         }
    21         return _instance;
    22     }
    23     private Helper() { }
    24     /// <summary>
    25     /// 若用户自定义了parent则使用,若没有则根据panelType自动设定。
    26     /// </summary>
    27     /// <param name="child">子物体</param>
    28     /// <param name="parent">父物体</param>
    29     public  void SetParent(GameObject child, Transform parent = null)
    30     {
    31         if(parent != null)
    32         {
    33             child.transform.SetParent(parent, true);
    34             child.transform.localScale = new Vector3(1, 1, 1);
    35             child.transform.localPosition = Vector3.zero;
    36         }
    37         else
    38         {
    39             if(child.GetComponent<BasePanel>()!= null)
    40             {
    41                 EPanelType panelType = child.GetComponent<BasePanel>().panelType;
    42                 switch (panelType)
    43                 {
    44                     case EPanelType.Normal:
    45                         child.transform.SetParent(normal);
    46                         break;
    47                     case EPanelType.Popup:
    48                         child.transform.SetParent(popup);
    49                         break;
    50                     case EPanelType.HideOther:
    51                         child.transform.SetParent(hiderOther);
    52                         break;
    53                     default:
    54                         Debug.LogError("错误,未知的窗体类型");
    55                         break;
    56                 }
    57                 child.transform.localScale = new Vector3(1, 1, 1);
    58                 child.transform.localPosition = Vector3.zero;
    59             }
    60             else
    61             {
    62                 Debug.LogError(GetType()+ "请检查此物体是否挂载了BasePanel类型脚本!");
    63             }
    64            
    65         }
    66     }
    67 }

    启动框架类StartGame.cs

     1 using UnityEngine;
     2 
     3 public class StartGame : MonoBehaviour
     4 {
     5   
     6     private GameObject uiRoot = null;
     7     void Start()
     8     {
     9         uiRoot = GameObject.FindGameObjectWithTag("UIRoot");
    10         if (uiRoot != null)          //已生成UIRoot
    11         {
    12             Destroy(uiRoot);
    13 
    14         }
    15         //获取UIRoot对象
    16         uiRoot = ResourceManager.GetInstance().LoadAsset<GameObject>(PrefabPathStr.uiRootPath);
    17       
    18         //修改克隆体的名字
    19         uiRoot.name = "UIRoot";
    20         //加载场景时不销毁UIRoot
    21         DontDestroyOnLoad(uiRoot);
    22 
    23         //加载登陆面板
    24         PanelManager.GetInstance().CreatePanel(PrefabPathStr.logOnPanelPath);
    25 
    26     }
    27 
    28 }

    测试代码LogOnPanel.cs

     1 using System.Collections;
     2 using System.Collections.Generic;
     3 using UnityEngine;
     4 
     5 public class LogOnPanel : BasePanel
     6 {
     7     private void Awake()
     8     {
     9         this.panelType = EPanelType.Normal;
    10     }
    11 
    12 }

    UIRoot预制体效果图

    LogOnPanel预制体效果图:

    运行效果图:

  • 相关阅读:
    PHP 指定的 CGI 应用程序由于未返回完整的一组 HTTP 头而产生错误行为。
    BPM触发事件
    封装继承多态到底讲的是什么
    .Net 为什么叫.Net 转载自 jerrylsxu 的博客
    C# 琐碎记忆 Message
    SQL Case
    C# 命名规范(部分)
    C# 反射
    C# 日志 log 配置文件
    C# 琐碎记忆 三元表达式
  • 原文地址:https://www.cnblogs.com/blackteeth/p/10197568.html
Copyright © 2011-2022 走看看