• 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文件里的变量名称要和代码里的变量名称一致,不然无法实别到。

  • 相关阅读:
    【转】使用TortoiseSVN搭建本地的版本控制库
    操作系统的大端小端
    从《王者荣耀》谈游戏的帧同步
    二叉搜索树的第K大节点
    Mysql千万级大表优化
    海量数据存储方案
    递归函数思维
    time_wait的快速回收和重用
    Nginx配置反向代理服务器
    MySQL-怎样使update操作sleep一段时间
  • 原文地址:https://www.cnblogs.com/shuanglu/p/8343511.html
Copyright © 2020-2023  润新知