遊戲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 解析方法的最簡測試演示。
namespaceTest { [Serializable] publicclassHero { //名稱 publicstringName; //等級 publicLevelMyLevel; } } namespaceTest { [Serializable] publicclassLevel { publicintHeroLevel; } }
/*** * *Title:"SUIFW"UI框架專案 *主題:演示Unity對Json解析API usingSystem.Collections; usingSystem.Collections.Generic; usingUnityEngine; namespaceTest { publicclassTestUnityJson:MonoBehaviour{ voidStart(){ HeroheroObj=newHero(); heroObj.Name="郭靖"; heroObj.MyLevel=newLevel(){HeroLevel=800}; //相當於如下寫法 //Levellev=newLevel(); //lev.HeroLevel=800; //heroObj.MyLevel=lev; //方法1:Json序列化工作(物件-->檔案) stringstrHeroInfo=JsonUtility.ToJson(heroObj); Debug.Log("測試1:得到的序列化後的字串="+strHeroInfo); //方法2:反序列化(Json檔案-->物件) HeroheroInfo2=JsonUtility.FromJson<Hero>(strHeroInfo); Debug.Log("測試2:得到反序列化物件數值,名稱:"+heroInfo2.Name+"等級:"+heroInfo2.MyLevel.HeroLevel); //方法3:測試覆蓋反序列化。 Herohero=newHero(); hero.Name="楊過"; hero.MyLevel=newLevel(){HeroLevel=500}; //Json序列化 stringheroInfo3=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版本 *ModifyRecoder: * * */ usingSystem.Collections; usingSystem.Collections.Generic; usingUnityEngine; namespaceTest { publicclassTestUnityJson2:MonoBehaviour{ voidStart() { //提取檔案,得到字串資料 TextAssetTaObj=Resources.Load<TextAsset>("People"); //反序列化檔案-->物件 PersonInfoperInfo=JsonUtility.FromJson<PersonInfo>(TaObj.text); //顯示物件中資料 foreach(PeopleperinperInfo.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版本 *ModifyRecoder: * * */ usingSystem; usingSystem.Collections; usingSystem.Collections.Generic; usingUnityEngine; namespaceSUIFW { publicinterfaceIConfigManager{ ///<summary> ///只讀屬性:應用設定 ///功能:得到鍵值對集合資料 ///</summary> Dictionary<string,string>AppSetting{get;} ///<summary> ///得到配置檔案(AppSeting)最大的數量 ///</summary> ///<returns></returns> intGetAppSettingMaxNumber(); } [Serializable] internalclassKeyValuesInfo { //配置資訊 publicList<KeyValuesNode>ConfigInfo=null; } [Serializable] internalclassKeyValuesNode { //鍵 publicstringKey=null; //值 publicstringValue=null; } }
第2步: 定義Json 解析異常類。
Json 的解析過程如果出錯,推薦使用我們自己定義的異常處理,為了更好的發現程式錯誤,所以自定義Json 解析異常類定義如下:
/*** * *Title:"SUIFW"UI框架專案 *主題:Json解析異常 *Description: *功能:專門負責對於JSon由於路徑錯誤,或者Json格式錯誤造成的異常,進行捕獲。 * *Date:2017 *Version:0.1版本 *ModifyRecoder: * * */ usingSystem; usingSystem.Collections; usingSystem.Collections.Generic; usingUnityEngine; namespaceSUIFW { publicclassJsonAnlysisException:Exception{ publicJsonAnlysisException():base(){} publicJsonAnlysisException(stringexceptionMessage):base(exceptionMessage){} } }
第3步:定義“配置管理器”類
開發實現IConfigManager 介面的通用配置管理器
/*** * *Title:"SUIFW"UI框架專案 *主題:基於Json配置檔案的“配置管理器” *Description: *功能: * *Date:2017 *Version:0.1版本 *ModifyRecoder: * * */ usingSystem; usingSystem.Collections; usingSystem.Collections.Generic; usingUnityEngine; namespaceSUIFW { publicclassConfigManagerByJson:IConfigManager { //儲存(鍵值對)應用設定集合 privatestaticDictionary<string,string>_AppSetting; ///<summary> ///只讀屬性:得到應用設定(鍵值對集合) ///</summary> publicDictionary<string,string>AppSetting { get{return_AppSetting;} } ///<summary> ///建構函式 ///</summary> ///<paramname="jsonPath">Json配置檔案路徑</param> publicConfigManagerByJson(stringjsonPath) { _AppSetting=newDictionary<string,string>(); //初始化解析Json資料,載入到(_AppSetting)集合。 InitAndAnalysisJson(jsonPath); } ///<summary> ///得到AppSetting的最大數值 ///</summary> ///<returns></returns> publicintGetAppSettingMaxNumber() { if(_AppSetting!=null&&_AppSetting.Count>=1) { return_AppSetting.Count; } else { return0; } } ///<summary> ///初始化解析Json資料,載入到集合眾。 ///</summary> ///<paramname="jsonPath"></param> privatevoidInitAndAnalysisJson(stringjsonPath) { TextAssetconfigInfo=null; KeyValuesInfokeyvalueInfoObj=null; //引數檢查 if(string.IsNullOrEmpty(jsonPath))return; //解析Json配置檔案 try{ configInfo=Resources.Load<TextAsset>(jsonPath); keyvalueInfoObj=JsonUtility.FromJson<KeyValuesInfo>(configInfo.text); } catch{ thrownewJsonAnlysisException(GetType()+"/InitAndAnalysisJson()/JsonAnalysisException!ParameterjsonPath="+jsonPath); } //資料載入到AppSetting集合中 foreach(KeyValuesNodenodeInfoinkeyvalueInfoObj.ConfigInfo) { _AppSetting.Add(nodeInfo.Key,nodeInfo.Value); } } } }
程式碼說明:
以上定義的“配置管理器”,可以對所有具備“鍵值對”特性的Json 配置檔案,做統一資料提取工作,從而對於“UI預設”、“遊戲物件”、“日誌配置檔案”、“語言國際化”等資訊,可以做統一處理,極大提供開發效率。以下筆者提供本UI框架需要用到的除企業日誌系統外,其他兩種配置檔案的截圖,供參考。
(企業級Log日誌中使用到的配置資訊)
(“UI預設” 路徑資訊Json配置檔案)
本篇就先寫到這,下篇 "遊戲UI框架設計(6)_訊息傳遞中心" 繼續。
轉載於:https://blog.51cto.com/liuguozhu/1932167