1. 劃分程序集的意義
在大型項(xiàng)目中辫诅,合理的規(guī)劃和拆分代碼模塊岭妖,設(shè)置合理的引用關(guān)系函喉,可以解除基礎(chǔ)框架-游戲模塊-三方插件的耦合呜舒。
如上圖中游戲模塊作為需要經(jīng)常改動(dòng)的模塊锭汛,它引用了基礎(chǔ)框架模塊和三方插件。而后者沒有對(duì)其的引用袭蝗。
如果按上圖劃分程序集并設(shè)置引用關(guān)系:代碼的依賴關(guān)系會(huì)因?yàn)槌绦蚣蕾嚤粡?qiáng)制限制唤殴。如果某個(gè)不規(guī)范的程序員擅自在基礎(chǔ)框架中添加了涉及到游戲模塊的代碼,那么Ta會(huì)發(fā)現(xiàn)代碼報(bào)錯(cuò)到腥,編輯器無法在基礎(chǔ)框架程序集中查到對(duì)游戲模塊程序集的代碼的引用朵逝。
如果基礎(chǔ)框架和游戲模塊同在同一個(gè)程序集中:代碼的依賴關(guān)系必須要靠個(gè)人的代碼能力管理。作為管理者必須要嚴(yán)格規(guī)范下屬并經(jīng)常review代碼乡范,不然不規(guī)范的下屬幾天就可能把基礎(chǔ)框架和游戲模塊揉合成一團(tuán)小貓玩過的毛線團(tuán)配名,很難理順啤咽!
2. 程序集與熱更新
在熱更新需求下的程序集劃分與普通的項(xiàng)目差別很小,基本通用渠脉,主要在于我們?nèi)绾蝿澐諥OT程序集和JIT程序集宇整,而且還有對(duì)于unity默認(rèn)的Assembly-CSharp程序集的定義。
例如上面的圖片中的例子芋膘,我們可以有2種劃分方案:
AOT程序集包括基礎(chǔ)框架模塊和三方插件鳞青,熱更程序集包括游戲模塊的1~N個(gè)程序集。這種方案下適用于基礎(chǔ)框架穩(wěn)固完善的項(xiàng)目为朋,因?yàn)榛A(chǔ)框架不會(huì)有大的變動(dòng)所以不需要頻繁更新整包臂拓;
AOT程序集僅包括三方插件(甚至三方插件也可以不包括),剩余所有的程序集作為熱更习寸。這種方案下基本所有內(nèi)容都可以熱更埃儿,適用于新項(xiàng)目的快速迭代。
但是劃分方案2中融涣,有個(gè)問題:
- 下載/加載ab資源等操作童番,是在需要熱更的基礎(chǔ)框架中;
- 加載熱更資源和加載dll等初始化操作威鹿,是在AOT程序集中剃斧,且會(huì)用到下載/加載ab資源代碼;
所以在上面的幾條前提下忽你,我們發(fā)現(xiàn)這種劃分方案下:AOT程序集中有很多對(duì)熱更程序集中代碼的調(diào)用幼东。
我們可以通過Assembly加載,通過反射調(diào)用到熱更的代碼科雳,但是這樣必然很繁瑣根蟹。還有另外一種方法,為了避免AOT引用熱更代碼糟秘,我們也可以在AOT中實(shí)現(xiàn)另外一套資源下載/加載邏輯简逮。當(dāng)然這2種方法都很麻煩,最好還是基礎(chǔ)框架的代碼(至少下載/加載ab資源的代碼)設(shè)置為AOT程序集尿赚。
3 Assembly-CSharp程序集
在上述2種方案中散庶,我們都要考慮一個(gè)特殊的程序集:unity默認(rèn)的Assembly-CSharp程序集。
如果自己添加的代碼凌净,如果沒有專門劃分程序集悲龟,那么就會(huì)被設(shè)置為默認(rèn)的Assembly-CSharp或Assembly-CSharp-Editor程序集。
3.1 默認(rèn)程序集的特殊之處
不確定性和混沌性:自定義的程序集必定包含在某個(gè)專屬的文件夾下或dll中冰寻,但是默認(rèn)程序集的代碼遍布整個(gè)項(xiàng)目目錄须教,藏于各個(gè)犄角旮旯之中,不便管理和統(tǒng)計(jì)斩芭。
擁有最大訪問權(quán)力:自定義的程序集需要設(shè)置對(duì)外部程序集的引用后轻腺,才可以在內(nèi)部使用相關(guān)的接口代碼羹奉。但是默認(rèn)程序集可以訪問項(xiàng)目內(nèi)所有的程序集(在勾選Auto Referenced的時(shí)候),它相當(dāng)于是處于程序集引用關(guān)系的金字塔頂部约计。
3.2 熱更中默認(rèn)程序集是否熱更诀拭?
以下兩種方案都可以,但是各有利弊:
- 我們可以將其定義為AOT程序集煤蚌,不引用任何熱更程序集耕挨,那么下載熱更資源,加載dll等操作均在這里實(shí)現(xiàn)尉桩。
- 我們也可以將其定義為熱更程序集筒占,那么下載熱更資源,加載dll等操作均在劃分的其他AOT程序集中實(shí)現(xiàn)蜘犁。
把Assembly-CSharp程序集當(dāng)作熱更程序集有個(gè)不好的地方翰苫,那便是我們隨意加入的測(cè)試代碼(沒有放在有程序集定義的文件夾下),某些導(dǎo)入的三方插件等等这橙,只要未定義過程序集奏窑,那么默認(rèn)就會(huì)加入到Assembly-CSharp程序集。所以會(huì)經(jīng)常誤把某些代碼打入熱更dll屈扎。為避免程序花費(fèi)時(shí)間和精力去檢查這些內(nèi)容埃唯,不建議用這種方案。
4. unity中如何劃分程序集
在一個(gè)普通的C#項(xiàng)目中鹰晨,我們可以在vs中右鍵程序集(項(xiàng)目)條目然后打開屬性墨叛,查看該程序集的相關(guān)設(shè)定。但是unity生成的項(xiàng)目中模蜡,我們是無法使用這個(gè)操作的漠趁。
因?yàn)槌绦蚣纳珊蛣澐质怯晌覀冊(cè)趗nity中處理,然后unity自動(dòng)生成忍疾。其中unity中用來劃分程序集的文件就是Assembly Definition闯传。
當(dāng)我們?cè)谀夸浿杏益I創(chuàng)建Assembly Definition 文件后,該目錄內(nèi)的所有代碼文件將被劃分為當(dāng)前定義的程序集膝昆。
我們通過Assembly Definition文件丸边,可以處理以下事情:
- 添加自定義的宏:Define Constraints;
- 添加刪除程序集的依賴:Assembly Definition Refercences;
- 選擇生效的平臺(tái):Platforms;
除了上面這些常用的功能,還有General選項(xiàng)下這些很有用的選項(xiàng):
- Allow ‘unsafe’ Code:是否啟用不安全的代碼荚孵;
- Auto Referenced:是否自動(dòng)被依賴;勾選后會(huì)被默認(rèn)的Assembly-CSharp程序集自動(dòng)依賴纬朝。所以如果我們想在Assembly-CSharp中隔離對(duì)當(dāng)前程序集的依賴收叶,取消勾選。
- No Engine References:不依賴于引擎提供的代碼模塊共苛。適用于可以在unity或其他平臺(tái)的項(xiàng)目中通用的程序集判没。
- Override References:可以手動(dòng)指定所依賴的預(yù)編譯的程序集蜓萄,因?yàn)閡nity項(xiàng)目中的預(yù)編譯程序集可以被其他默認(rèn)依賴,勾選后當(dāng)前程序集可以選擇(不)依賴某個(gè)預(yù)編譯的程序集澄峰。
- Root Namespace: 當(dāng)前程序集的默認(rèn)命名空間嫉沽,填寫后我們使用unity添加新代碼文件,會(huì)自動(dòng)添加命名空間俏竞。我測(cè)試只有在unity中創(chuàng)建才生效绸硕。