數(shù)據(jù)持久化設(shè)計(jì)
很久沒有總結(jié)做過的東西了,今天來小結(jié)一下最近兩天做數(shù)據(jù)持久化的一些心得;所謂數(shù)據(jù)持久化簡單來說,就是保存和加載。目前只做了切換場景時保存標(biāo)記為持久化對象的單位的狀態(tài),等重新切換回來時,再加載;和退出游戲加載存檔的機(jī)制是一樣的。我選擇使用了二進(jìn)制存檔的方式,思路大致如下:
1、給游戲?qū)ο蟮幕愔屑右粋€變量和一個guid的字符串
這里的Const.emptyGuid是存儲的一個全局值,Guid.empty.ToString();
2、在基類或其派生類的面板工具中添加自動生成Guid的邏輯
生成Guid的代碼也很簡單
3、將ForceUpdateGuid設(shè)置成菜單功能,由于Guid無法被編輯,所以要做一個自動全部重新生成的功能。(因?yàn)椴幌M鸊uid被手動編輯,1來操作麻煩,2來防止誤觸,自動創(chuàng)建更能保證他的唯一性;這個自動創(chuàng)建最開始是打算在Awake時執(zhí)行,但是后來還是打算做成菜單功能,擔(dān)心Awake創(chuàng)建會有問題,具體啥問題沒去想,總之自我感覺,在Awake里放執(zhí)行邏輯要謹(jǐn)慎,特別是AlwaysExecute的組件,所以用菜單功能更能保證安全性,一次創(chuàng)建,永久保存)為了進(jìn)一步保證工具的安全性(雖然現(xiàn)在只有我一個人在用)我加了一個提示框:

代碼如下:
3、在場景加載時,更新游戲?qū)ο蟮臓顟B(tài),判定游戲?qū)ο蟮奈ㄒ恍杂蓀ersistStr決定。后面的邏輯都比較順暢了,就不贅述了。
遇到的坑大致如下:
1、InstanceID不能保證對象唯一性,每次進(jìn)出場景時值會發(fā)生變化,必須創(chuàng)建一個唯一標(biāo)識的Guid
2、在編輯器中調(diào)用其target指向的類的方法要謹(jǐn)慎,有時候可能導(dǎo)致游戲運(yùn)行的結(jié)果異常。
3、枚舉enum和字典Dictionary不能被序列化(這里的序列化指C#的[Serializable]),使用二進(jìn)制存檔需要將數(shù)據(jù)分離出來一個可以被序列化的類中,所以要保證每個成員都能被序列化。將不能序列化的enum和Dictionary存儲為可以被序列化的int和List,然后反序列化時再按照需要組裝成需要的結(jié)構(gòu)。
目前還有一些沒有完善的地方,比如在3號地圖打開通往1號地圖的后門時,需要對1號地圖的入口進(jìn)行數(shù)據(jù)操作;至于為什么當(dāng)初沒有考慮將所有關(guān)卡設(shè)計(jì)為同一張地圖,這個也是為了讓關(guān)卡之間存在一定的獨(dú)立性,不存在一個機(jī)制的出現(xiàn),會出現(xiàn)牽一發(fā)而動全身的問題。雖然我把這款游戲定義為開放世界,但地圖之間的獨(dú)立性還會分開比較好,畢竟第一款游戲,不能在性能問題上出現(xiàn)敗筆。