设计一个简单的UI框架,实现不同模块之间相互转换,使用单例实现。

实现不同模块或窗口的互相切换,其实用一些代码都可以实现,但是使用UI框架不仅方便后续修改添加删除,同时在做出扩展效果时,也可以快速实现。由于我还是学生,这些搭建UI的材料都是以前玩的一些小游戏里面,比较简陋。

先看一下大体的思维导图。

 做出的成果开始的时候只有一个摄像机,

 然后开始运行以后出现一个UI界面如下:

 然后随便点击几个UI界面:

 实现UI窗口的切换。

下面开始正式内容:搭建UI的部分我就不展示了,大家可以自己先搭建几个UI界面,并设成预设体,在Assets内新建文件夹Resources(必须时这个名字不能错),在Resources里新建Panels,将预设体放进去。

 设计一个Json文件,里面存放不同模块的信息。我的名字为UIPanelConfig.Json,在Resources文件夹里的Configuration文件夹里,要记住存放的位置,后面要用。Json的内容为:

{
"AllData":
[
  {
	"SceneName":"MainScene",
	"Data":
	[
		{
			"PanelName":"MainPanel",
			"PanelPath":"Panels/MainPanel"
		},
		{
			"PanelName":"BagPanel",
			"PanelPath":"Panels/BagPanel"
		},
		{
			"PanelName":"HeroEquipPanel",
			"PanelPath":"Panels/HeroEquipPanel"
		},
		{
			"PanelName":"HeroMsgPanel",
			"PanelPath":"Panels/HeroMsgPanel"
		},
		{
			"PanelName":"NormalWindowPanel",
			"PanelPath":"Panels/NormalWindowPanel"
		},
		{
			"PanelName":"SystemPanel",
			"PanelPath":"Panels/SystemPanel"
		},
		{
			"PanelName":"TaskPanel",
			"PanelPath":"Panels/TaskPanel"
		} 
	]
  }
   
  ]
 }

写因为后面要频繁使用单例,所以先写一个单例框架。定义一个命名空间为UIFrame

using System;
namespace UIFrame
{
    public class Singleton<T> where T : class
    {
        //单例对象
        private static T _singleton;

        //获取单例
        public static T Instance
        {
            get
            {
                if (_singleton == null)
                {
                    _singleton= (T)Activator.CreateInstance(typeof(T), nonPublic: true);

                }
                return _singleton;
            }
        }
    }
}

编写一个资源管理类为:AssetsManager,避免每次资源被调用后直接销毁而产生内存浪费,所以做一个缓存机制。

using System.Collections.Generic;
using UnityEngine;

namespace UIFrame
{
    public class AssetsManager : Singleton<AssetsManager>
    {

        //私有构造
        private AssetsManager()
        {
            assetsCache = new Dictionary<string, Object>();
        }
        //资源缓存
        private Dictionary<string, Object> assetsCache;

        public Object GetAssets(string path)
        {
            //要返回的资源
            Object assetObj = null;
            //尝试从字典中获取该路径所对应的资源
            if (!assetsCache.TryGetValue(path,out assetObj))
            {
                //通过Resource加载资源
                assetObj = Resources.Load(path);
                //将资源存进缓存
                assetsCache.Add(path, assetObj);
            }
            
            return assetObj;
        }
        private Object TryGetValueTest(string key)
        {
            Object assetObj = null;
            //尝试获取资源
            //如果获取到了则isGet==True
            //如果没有获取到则isGet==False,assetObj就没有获取到值
            bool isGet= assetsCache.TryGetValue(key, out assetObj);

            if(isGet)
            {
                //assetObj已经获取到值了
                return assetObj;
            }
            else
            {
                //Resource加载该资源
                assetObj = Resources.Load(key);
                //放入缓存
                assetsCache.Add(key, assetObj);
                //返回他
                return assetObj;
            }
        }
    }
}

写一个类:SystemDefine。在里面存放一些常用的常数或字符串。

namespace UIFrame
{
    public static class SystemDefine
    {

        #region Conciguration Path
        public const string PanelConfigPath = "Configuration/UIPanelConfig";
        public const string LocalizationConfigPath = "Configuration/UILanguageTextConfig";

        #endregion
        #region Scene ID
        public enum SceneID
        {
            MainScene = 0
        }
        #endregion

        #region Widget Token
        public static string[] WIDGET_TOKEN=new string[] { "_F","_S","_T"} ;
        #endregion

    }
}

接下来编写一个用来解析和调用Json数据的代码。名字为JsonDataManager。这里面的一些方法就需要调用SystemDefine类里的固定字符串了。解析Json利用Unity自带的类JsonUtility(功能较少,但是简单)。

TextAsset panelConfig = AssetsManager.Instance.GetAssets(SystemDefine.PanelConfigPath) as TextAsset;//将Json转换成TextAsset类型,然后利用JsonUtility.FromJson解析,解析后的结构与JsonPanelModel类型相同。创建一个字典类型panelDataDic,把解析后的数据panelData放入到字典里,然后在下面的FindPanelPath方法内,只要在外界调用时传入一个panelName,则返回原本Json文件里的路径。

using System.Collections.Generic;
using UnityEngine;
namespace UIFrame
{
    public class JsonDataManager :Singleton<JsonDataManager>
   {
        private JsonDataManager()
        {

            panelDataDic = new Dictionary<int, Dictionary<string, string>>();
            localizationDic = new Dictionary<int, Dictionary<string, string[]>>();

            ParsePanelData();
            ParseLocalizationData();


        }

        #region Saved Structure
        //Panel解析后的数据,不利于检索
        private JsonPanelModel panelData;
        //本地化内容解析后的数据
        private JsonLocalizationModel localizationData;

        //Panel解析后的数据当作字典处理,容易检索
        private Dictionary<int, Dictionary<string, string>> panelDataDic;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值