打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【游戏UI框架设计(五): 配置管理与应用】
    在开发企业级游戏/VR/AR产品时候,我们总是希望可以总结出一些通用的技术体系,框架结构等,为简化我们的开发起到“四两拨千金”的作用。所谓“配置管理”是指一个游戏项目(软件项目),很多需要经常变化的需求或者数据,最好以配置文件的形式存在,从而代替“硬编码”方式。
      这里笔者就对游戏产品中大量应用到动态加载的情形,开发出一套通用的配置管理(脚本)工具。该工具可以很方便的对于具备“键值对”特性的配置文件做统一的数据提取处理,特别适合如下应用情形等:
  • “UI预设”/“游戏对象预设”的动态加载。
  • 企业级Log 日志系统中关于配置信息(日志的保存路径、日志级别信息)的动态加载。
  • 资源(语言)国际化系统中关于语言信息的动态加载。


下图给出本UI框架用到的"语言国际化"对应的Json 配置文件:


(“语言国际化”中文信息的Json配置文件)

目前(2017)国际国内普遍采用的配置管理方式主要有两种: XML与Json 方式,两者各有优缺点:
  •   XML: 对于数据的精确表示、易读性很高。
        微软很多的项目都内置对XML作为配置文件的支持。       (例如:网站项目:ASP.Net、 WinForm 等)        
        缺点是读写速度慢,这个问题在移动端尤其突出。

  • Json: 读写速度快,但是易读性没有XML好,但是可以接受。
        所以本框架项目都采用Json作为配置文件。 考虑到目前移动端游戏/VR/AR产品的大量应用,所以笔者在此重点介绍基于Json配置文件的数据解析与配置管理。(Json比传统的XML作为配置文件使用,具备解析速度快,文件尺寸小等突出优点)


什么是Json JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。  JSON 语法特点: (JSON 语法是 JavaScript 对象表示语法的子集)
  •     数据在键值对中,数据由逗号分隔。

  •     花括号保存对象,方括号保存数组。
      JSON 数据的书写格式是:名称/值对  "firstName":"John"具体示例



Json的解析方式: 目前(2017)国际国内对于Json 的解析主要有以下几种方式
  • .NET自带的运行时序列化和反序列化json工具。
   命名空间System.Runtime.Serialization.Json   缺点是需要编写大量代码,自己来封装一些实用方法,不推荐。

  •   插件解析:
  目前国内用的最多的Json解析插件:litejson

由于Unity公司也看到了Unity项目中对于大量Json 文件解析操作的需求,所以在.3以上版本开始原生提供Json的解析API,如下图:




对于Json 的初学者,为了更好的理解后面的配置管理技术讲解,特提供使用Unity的API 对Json 配置文件的解析示例:

Json基本解析示例
示例1:
对于Unity 原生支持Json 解析方法的最简测试演示。

[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
namespace Test
{
    [Serializable]
        public class Hero
    {
        //名称
        public string Name;
        //等级
        public Level MyLevel;
    }
}

[C#] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
namespace Test
{
    [Serializable]
        public class Level
        {
            public int HeroLevel;
        }
}

[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
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
/***
 *
 *    Title: "SUIFW" UI框架项目
 *           主题: 演示Unity 对Json 解析API   
  
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Test
{
        public class TestUnityJson : MonoBehaviour {
                void Start () {
                        Hero heroObj=new Hero();
                    heroObj.Name = "郭靖";
                    heroObj.MyLevel = new Level() {HeroLevel = 800};
            //相当于如下写法
            //Level lev=new Level();
            //lev.HeroLevel = 800;
            //heroObj.MyLevel = lev;
                    //方法1: Json 序列化工作(对象--> 文件)
                    string strHeroInfo = JsonUtility.ToJson(heroObj);
            Debug.Log("测试1: 得到的序列化后的字符串="+strHeroInfo);
                    //方法2: 反序列化(Json文件--> 对象)
                    Hero heroInfo2 = JsonUtility.FromJson<Hero>(strHeroInfo);
            Debug.Log("测试2:得到反序列化对象数值,名称:  "+heroInfo2.Name+" 等级:  "+heroInfo2.MyLevel.HeroLevel);
                    //方法3: 测试覆盖反序列化。
            Hero hero=new Hero();
                    hero.Name = "杨过";
                    hero.MyLevel = new Level() {HeroLevel = 500};
             
            //Json 序列化
                    string heroInfo3 = JsonUtility.ToJson(hero);
            //测试覆盖反序列化
            JsonUtility.FromJsonOverwrite(heroInfo3, heroObj);
            Debug.Log("测试3, 得到再次反序列化覆盖的对象信息,名称:  "+heroObj.Name+"  等级: "+heroObj.MyLevel.HeroLevel);
                }
                 
        }
}


示例2:      对于Json 文件的实战性测试用例演示。

[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
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
/***
 *
 *    Title: "SUIFW" UI框架项目
 *           主题: 对于Unity中Resource 目录下的Json 文件的解析Demo
 *    Description:
 *           功能: yyy
 *                 
 *    Date: 2017
 *    Version: 0.1版本
 *    Modify Recoder:
 *   
 *  
 */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Test
{
        public class TestUnityJson2 : MonoBehaviour {
                void Start ()
                {
             //提取文件,得到字符串数据
                     TextAsset TaObj=Resources.Load<TextAsset>("People");
             //反序列化  文件-->对象
             PersonInfo perInfo=JsonUtility.FromJson<PersonInfo>(TaObj.text);
             //显示对象中数据
             foreach (People per in perInfo.People)
                     {
                        Debug.Log(" ");
                Debug.Log(string.Format("name={0},Age={1}",per.Name,per.Age));
                     }
                }
                 
        }
}



以上代码解释如下: Unity(5.3以上版本)提供的JsonUtility提供了三个重要方法
  • JsonUtility.ToJson()//表示进行序列化操作,把对象序列化为字符串。
  • JsonUtility.FromJson();//表示进行反序列化操作,把Json字符串反序列化为对象。
  • JsonUtility.FromJsonOverwrite();//是覆盖方式进行反序列化。
有了以上技术储备,我们就可以进行开发“通用配置管理器”了。

第1步: 首先定义通用配置管理器接口与辅助类。

[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
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
/***
 *
 *    Title: "SUIFW" UI框架项目
 *           主题: 通用配置管理器接口  
 *    Description:
 *           功能:
 *                基于“键值对”配置文件的通用解析
 *                 
 *    Date: 2017
 *    Version: 0.1版本
 *    Modify Recoder:
 *   
 *  
 */
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SUIFW
{
        public interface IConfigManager  {
        /// <summary>
        /// 只读属性: 应用设置
        /// 功能: 得到键值对集合数据
        /// </summary>
            Dictionary<string, string> AppSetting { get; }
        /// <summary>
        /// 得到配置文件(AppSeting)最大的数量
        /// </summary>
        /// <returns></returns>
            int GetAppSettingMaxNumber();
        }
    [Serializable]
    internal class KeyValuesInfo
    {
        //配置信息
        public List<KeyValuesNode> ConfigInfo = null;
    }
    [Serializable]
    internal class KeyValuesNode
    {
        //键
        public string Key = null;
        //值
        public string Value = null;
    }
}



第2步: 定义Json 解析异常类。
Json 的解析过程如果出错,推荐使用我们自己定义的异常处理,为了更好的发现程序错误,所以自定义Json 解析异常类定义如下:

[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/***
 *
 *    Title: "SUIFW" UI框架项目
 *           主题: Json 解析异常
 *    Description:
 *           功能:专门负责对于JSon 由于路径错误,或者Json 格式错误造成的异常,进行捕获。
 *                 
 *    Date: 2017
 *    Version: 0.1版本
 *    Modify Recoder:
 *   
 *  
 */
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SUIFW
{
        public class JsonAnlysisException : Exception {
            public JsonAnlysisException() : base(){}
            public JsonAnlysisException(string exceptionMessage) : base(exceptionMessage){}
        }
}


第3步:定义“配置管理器”类
开发实现IConfigManager接口的通用配置管理器

[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
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
/***
 *
 *    Title: "SUIFW" UI框架项目
 *           主题:基于Json 配置文件的“配置管理器” 
 *    Description:
 *           功能:
 *                 
 *    Date: 2017
 *    Version: 0.1版本
 *    Modify Recoder:
 *   
 *  
 */
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SUIFW
{
        public class ConfigManagerByJson : IConfigManager
        {
        //保存(键值对)应用设置集合
            private static Dictionary<string, string> _AppSetting;
        /// <summary>
        /// 只读属性: 得到应用设置(键值对集合)
        /// </summary>
            public Dictionary<string, string> AppSetting
            {
                get { return _AppSetting; }
            }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="jsonPath">Json配置文件路径</param>
            public ConfigManagerByJson(string jsonPath)
            {
                _AppSetting=new Dictionary<string, string>();
            //初始化解析Json 数据,加载到(_AppSetting)集合。
            InitAndAnalysisJson(jsonPath);
            }
        /// <summary>
        /// 得到AppSetting 的最大数值
        /// </summary>
        /// <returns></returns>
            public int GetAppSettingMaxNumber()
            {
            if (_AppSetting!=null && _AppSetting.Count>=1)
            {
                return _AppSetting.Count;
            }
            else
            {
                return 0;
            }
            }
        /// <summary>
        /// 初始化解析Json 数据,加载到集合众。
        /// </summary>
        /// <param name="jsonPath"></param>
            private void InitAndAnalysisJson(string jsonPath)
        {
            TextAsset configInfo = null;
            KeyValuesInfo keyvalueInfoObj = null;
            //参数检查
            if (string.IsNullOrEmpty(jsonPath)) return;
            //解析Json 配置文件
            try{
                configInfo = Resources.Load<TextAsset>(jsonPath);
                keyvalueInfoObj=JsonUtility.FromJson<KeyValuesInfo>(configInfo.text);
            }
            catch{
                throw new JsonAnlysisException(GetType() + "/InitAndAnalysisJson()/Json Analysis Exception ! Parameter jsonPath=" + jsonPath);
            }
            //数据加载到AppSetting 集合中
            foreach (KeyValuesNode nodeInfo in keyvalueInfoObj.ConfigInfo)
            {
                _AppSetting.Add(nodeInfo.Key,nodeInfo.Value);
            }
        }
        }
}


代码说明: 以上定义的“配置管理器”,可以对所有具备“键值对”特性的Json 配置文件,做统一数据提取工作,从而对于“UI预设”、“游戏对象”、“日志配置文件”、“语言国际化”等信息,可以做统一处理,极大提供开发效率。以下笔者提供本UI框架需要用到的除企业日志系统外,其他两种配置文件的截图,供参考。

(企业级Log日志中使用到的配置信息)



(“UI预设” 路径信息Json配置文件)


本篇就先写到这,下篇 "游戏UI框架设计(6)_消息传递中心"继续。





本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
接口测试“八重天”---RestAssured
ASP.NET Core MVC/API(一)
NETCore 读取JSON配置文件
自定义XML动态配置程序
NetCore 启动地址配置详解
Asp.Net读取配置文件
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服