游戏UI框架设计(五): 配置管理与应用

游戏UI框架设计(五)

--配置管理与应用

在开发企业级游戏/VR/AR产品时候,我们总是希望可以总结出一些通用的技术体系,框架结构等,为简化我们的开发起到“四两拨千金”的作用。所谓“配置管理”是指一个游戏项目(软件项目),很多需要经常变化的需求或者数据,最好以配置文件的形式存在,从而代替“硬编码”方式。

这里笔者就对游戏产品中大量应用到动态加载的情形,开发出一套通用的配置管理(脚本)工具。该工具可以很方便的对于具备“键值对”特性的配置文件做统一的数据提取处理,特别适合如下应用情形等:

1:“UI预设”/“游戏对象预设”的动态加载。

2:企业级Log 日志系统中关于配置信息(日志的保存路径、日志级别信息)的动态加载。

3:资源(语言)国际化系统中关于语言信息的动态加载。

下图给出本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 文件解析操作的需求,所以在Unity5.3以上版本开始原生提供Json的解析API,如下图:

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

Json基本解析示例

  • 示例1:

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

namespace Test
{
    [Serializable]
public class Hero
    {
        //名称
        public string Name;
        //等级
        public Level MyLevel;

    }
}

namespace Test
{
    [Serializable]
public class Level
{
    public int HeroLevel;

}
}
/***
 * 
 *    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 文件的实战性测试用例演示。

/***
 * 
 *    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步: 首先定义通用配置管理器接口与辅助类。

代码如下:

/***
 * 
 *    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 解析异常类定义如下:

/***
 * 
 *    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 接口的通用配置管理器

/***
 * 
 *    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)_消息传递中心" 继续。

时间: 2024-10-05 05:58:26

游戏UI框架设计(五): 配置管理与应用的相关文章

游戏UI框架设计(五): 配置管理与应用

游戏UI框架设计(五) --配置管理与应用 在开发企业级游戏/VR/AR产品时候,我们总是希望可以总结出一些通用的技术体系,框架结构等,为简化我们的开发起到"四两拨千金"的作用.所谓"配置管理"是指一个游戏项目(软件项目),很多需要经常变化的需求或者数据,最好以配置文件的形式存在,从而代替"硬编码"方式.      这里笔者就对游戏产品中大量应用到动态加载的情形,开发出一套通用的配置管理(脚本)工具.该工具可以很方便的对于具备"键值对&

游戏UI框架设计(7): 资源国际化技术

游戏UI框架设计(7) --资源国际化技术 说起"资源国际化"技术,个人认为可以追述到微软Window2000 PC操作系统的发布,在这之前windows98操作系统的开发都是先由美国总部出一个英文版本,然后在发布windows 版本之后的大约一年后,全世界其他语言版本的操作系统才能面世. 在这一年中,就是微软驻各个国家分公司的多语言版本的翻译工作,需要从操作系统的核心到外围软件,全部翻译为所在国家语言,不留死角.       这种情况对于微软来说需要为多语言版本付出额外非常大的经济负

游戏UI框架设计(四) : 模态窗体管理

游戏UI框架设计(四) --模态窗体管理 我们在开发UI窗体时,对于"弹出窗体"往往因为需要玩家优先处理弹出小窗体,则要求玩家不能(无法)点击"父窗体",这种窗体就是典型的"模态窗体".在此笔者设计了四种模式类型:完全透明.半透明.低透明度.透明且可以穿透. (透明不能穿透) (半透明不能穿透) (低透明度,不能穿透) 对于"模态窗体"的基本实现原理是: 在弹出窗体的后面增加一层"UI遮罩窗体",当需要弹出

游戏UI框架设计(三) : 窗体的层级管理

游戏UI框架设计(三) ---窗体的层级管理 UI框架中UI窗体的"层级管理",最核心的问题是如何进行窗体的显示管理.窗体(预设)的显示我们前面定义了三种类型: 普通.隐藏其他.反向切换.代码如下: "普通显示"模式允许多个窗体同时显示,这种类型应用最多.例如RPG中的主城界面(见下图). "隐藏其他界面" 模式一般应用于全局性的窗体.我们在开发此类窗体时,为了减少UI渲染压力.提高Unity渲染效率,则设置被覆盖的窗体为"不可见&qu

游戏UI框架设计(二) : 最简版本设计

最简版本设计 --最简版本设计 为降低难度决定先讲解一个最简版本,阐述UI框架的核心设计理念.这里先定义三个核心功能: 1:UI窗体的自动加载功能. 2:缓存UI窗体. 3:窗体生命周期(状态)管理. UI框架设计主要目的,就是尽可能的完成一些与具体游戏功能逻辑无关的一些底层事务性的功能实现.这些功能最好是自动或者是半自动的实现,无须客户程序(调用框架的程序)过多处理与关心. 对于以上功能,笔者定义了UI框架的相关四个核心类: BaseUIForms    基础UI窗体脚本(父类,其他窗体都继承

WisDom.Net 框架设计(五) 权限设计

WisDom.Net --权限设计 1.需求分析     基本在所有的管理系统中都离不开权限管理.可以这么说,权限管理是管理系统的核心所在. 权限管理说白一些就是每个人能够做什么,不能够做什么.可以说是一套规则.下面就说一下,在wisdom.net中的权限     1. 控制用户修改和删除数据.即 用户编辑和删除自己创建的数据,但是只能编辑和删除比自己权限小的人创建的数据     2. 模块的控制. 用户只能访问自己被授权访问的模块,不能访问其他模块     3. 用户被赋予不同的角色,各个角色

《开源框架那些事儿22》:UI框架设计实战

UI是User Interface的缩写,通常被认为是MVC中View的部分,作用是提供跟人机交互的可视化操作界面.MVC中Model提供内容给UI进行渲染,用户通过UI框架产生响应,一般而言会由控制层调用业务逻辑进行处理,并把处理结果以Model方式返回View,再次渲染.UI框架的大致过程就是如此,按实现方式可以分为RIA和瘦客户端方式,目前基于B/S的瘦客户端方式比较流行.UI框架套路上很简单,但是想要做好可就不容易了.目前基于MVC的框架灿若繁星,不客气的说是个软件公司就有自己的技术框架

自己动手设计并实现一个linux嵌入式UI框架(设计)

看了"自己动手设计并实现一个linux嵌入式UI框架"显然没有尽兴,因为还没有看到庐山真面目,那我今天继续,先来说说,我用到了哪些知识背景.如:C语言基础知识,尤其是指针.函数指针.内存分布,linux 基础知识.如消息队列.framebuffer.多线程.多线程同步.等,数据结构.算法(如链表.队列等),window .netframework 框架设计思想,设计模式如 mvc.观察者.单例.工厂等.知识点有点多,每个知识点有机的组合在一起,形成了一个知识网,构成了一个系统.以上提到

弱交互移动游戏服务器端框架设计

很早前即有想法设计一套稳定.高效.安全的弱交互移动网络游戏服务器端基础框架,前些天初步完成简单的初稿文档.初版设计参考了印象里以前的一些工作经历经验.这些经历经验虽已日渐模糊,但从它们这里,自己获益良多. 初稿文档暂只是简单记录了目前想到,或觉得比较重要的内容(或许会更新),具体细节等涉及较少.可能我会在业余时间里一点点实现本文所述框架,只是开发计划暂无法预期,毕竟精力很有限. 1.功能描述 1.1) 弱交互移动休闲类游戏服务器端基础框架(以房间为游戏单位,诸如棋牌类游戏) 1.2) 相较传统的