KSFramework是一個Unity 5 Asset Bundle開發框架和工具集,專注于運行時熱重載,使用了SLua作為腳本引擎。
策劃與程序的橋梁
執行策劃在游戲開發的過程中的主要工作是什么?當然就是和Excel打交道了。大量的Excel數據表,最終會被演變成游戲的配置數據。日常游戲開發中,策劃編輯配置表一般有兩種方式:
- 編譯式:策劃編輯Excel,經過中間程序轉成csv、lua、json等程序可讀的文本格式;
- 直接擼式:策劃直接編輯Lua和使用Excel編輯TSV(CSV)等程序可讀的格式;
而程序讀取,理論上也因此有幾種方式:
- 自動生成配置讀取代碼:自動根據策劃編輯的Excel和規范,自動生成所有加載配置表的代碼;
- 手工寫讀取配置表的代碼:這是常見的方式,但往往一個項目下來,手寫的配置表的代碼不但大量,而且伴隨策劃配置的修改需要頻繁的維護;
對策劃來說,直接擼Lua或csv,體驗肯定不如直接編輯Excel來得爽快;對程序來說,讀表這種無技術含量的重復勞動,自然不如自動來得爽快。
KEngine中的配置模塊,使用了編譯式配置表,對Excel表有輕度的規范,策劃可以根據自身需要,添加文檔、注釋、圖標、批注等等各種輔助信息;并自動化生成出程序代碼配置表加載API,供程序直接使用。
配置表的編輯和編譯
KEngine中,配置表源文件,即編譯前的表,默認放置在Product/SettingSource目錄中;編譯后的配置文件放置在Assets/StreamingAssets/Setting目錄中。
Excel表格規則
該目錄的Excel文件都要遵循以下的4條規則:
- 第一個表單(Sheet)為需要編譯的內容;
- 表單的第一行是列名,如Id,Name等;
- 表單的第二行是列配置信息,如string/default,意思是列是string字符串類型,默認值是default; KEngine目前只使用前兩位信息;
- 表單的第三行是注釋,可以添加對列名的一些解釋,最常用莫過于為英文的列明配上中文的注釋了;
最終效果如圖:
注釋的行或列
除了第三行注釋行,配置表模塊還有兩個添加注釋的規則:
- 表單中,非頭三行內容,行的第一個單元格內容為“#”或“Comment”時,認為這一行是注釋行;
- 表單中,列名單元格內容為“#”或“Comment”時,認為這一列是注釋列;
拆分表格
日常的開發中,我們有時候會嫌一個Excel文件內容過多,希望將其進行拆分;同時也方便多人協作。
KEngine在編譯時,對文件名處理施展了一點點魔法:當文件名中存在+號時,會裁掉+號后邊的內容。
比如這3個文件:AppConfig+A.xlsx,AppConfig+B.xlsx,AppConfig+C.xlsx,在編譯時,會統一合并成AppConfig.xlsx。
但是要注意,務必確保這三個文件的表頭信息要一樣的。
配置表格的編譯
TSV,類似CSV,即Tab-sepertated Values,類似CSV表格,僅僅是分隔符從逗號變成了Tab。 就我公司所經歷的所有游戲項目,策劃均直接用Excel擼TSV格式配置表。
KEngine配置表編譯的本質,其實就是——把Excel文件轉換成純文本TSV格式文件。而在編譯過程中,會刪掉注釋內容:第三行的注釋,帶#井號的注釋等。
上圖中的Excel,經過編譯后變成的TSV文件內容:
如何在Unity中觸發KEngine對Excel表格編譯?
執行菜單KEngine->Setting中的兩個編譯配置表功能項:
- Force Compile Settings + Code:強制重新編譯所有的表,并且自動生成配置表代碼(會觸發Unity重新編譯)
- Quick Compile Settings:差異化編譯配置表,不重新自動生成配置表代碼
配置表的文件監測
為了方便開發,在打開Unity編輯器后KEngine會對所有的配置表源文件進行監測,當發現Excel文件有改動,Unity編輯器就會彈框請求進行配置表重新編譯(執行Quick Compile Settings差異化編譯)
不過,當修改配置表時并沒有打開帶有KEngine的Unity工程,就無法監測到配置表的變更,這時就需要手工執行菜單的配置表格編譯了。
配置表讀取的代碼生成
根據Excel配置表的頭部信息,KEngine會在Unity Assets根目錄(可通過EngineConfigs.txt這個INI文件進行配置)生成一個AppSettings.cs文件。這個文件包含了所有的配置表的讀取代碼。
直接來看看配置表代碼的調用方法——獲取所有、獲取某個、熱重載:
// 獲取所有的配置項
foreach (GameConfigSetting config in GameConfigSettings.GetAll()) // Get all Configs
{
Debug.Log(string.Format("C# Read Config, Key: {0}, Value: {1}", config.Id, config.Value));
}
// 獲取指定Key的配置項,Key為第一列
var testConfig = GameConfigSettings.Get("Test"); // Get by key
// 熱重載
GameConfigSettings.GetInstance().ReloadAll(); // Reload while settings recompile
Excel表GameConfig.xlsx,會生成一個類GameConfigSettings,放置在AppSettings.cs代碼文件中。
惰式初始化
生成的代碼中,采用了惰式初始化方式進行配置表的加載: 即第一次使用時進行初始化。
從而避免游戲啟動時的集中式初始化,降低啟動時間,優化執行性能。
// 預熱GameConfig表
GameConfigSettings.GetInstance(),
// 預熱所有的表
SettingsManager.AllSettingsReload();
可是,實際開發過程中,我就是想針對某些表,先初始化,再進游戲?
根據第一次使用時進行初始化的原則,強制在初始化階段進行一次調用就可以單例調用,就可以觸發初始化。
熱重載
對策劃來說,簡單的修改Excel配置表后,往往需要重啟游戲,來看修改的效果。
KEngine配置表提供一種方法,可以在不重啟游戲的前提下,重載配置表,來立即查看效果。
生成的配置表代碼中,會監測其加載過的編譯后的配置文件,當配置文件發生變化,就會進行重載。
如果文件監測失靈,你也可以通過菜單項來主動重載:
其他
既然KEngine中使用了Excel這種非純文本格式進行配置表的編輯,那么在配合SVN等版本管理工具時,如何進行差異化的配置表比較?可參詳:《KEngine:Excel如何進行SVN協作、差異比較?》