本文參考:
https://zhuanlan.zhihu.com/p/107270501
UE4模塊的加載方式
待補充
Modules
模塊是什么?一堆dll 類的集合,UE4被分為了1000個模塊
有什么作用?組織代碼,可移植性復用性,可以獲得更快的編譯和鏈接性能,也可以確認模塊何時加載
如何做一個Module? B U I L D
Build
Build,建立一個固定的目錄
[YourModuleName].Build.cs文件的作用用
描述如何編譯模塊、模塊的依賴等等
模塊的編譯只取決於.Target.cs和.Build.cs而不取決於sln
一個最少代碼的模塊包括:

和模塊名相同的C#類
構造函數中處理模塊的依賴性,必須依賴Core,里面包括了很多模塊相關代碼
Use
use 使用模塊

模塊的代碼並不是默認對其他的模塊暴露的
你需要隊每個函數或者類進行顯式的指定他是否導出
如果你不打算暴露任何代碼到模塊外,你可以不用分private和public的文件夾

這些代碼在藍圖中可以訪問,但是在其他模塊中不能使用
通過給UCLASS添加MinimalAPI(最小)標識來表示將其顯式導出到可以被其他模塊使用

要將某個函數暴露給其他模塊使用必須在函數前添加[YourModuleName]_API,全部大寫字母

要將整個類暴露就在類前加[YourModuleName]_API,全部大寫字母,這樣整個類的public部分都會暴露

由於這個類依賴了Actor類,所以我們在模塊的編譯時候會報錯

要用的話,就需要添加頭文件、添加模塊依賴關系

這里在publicDependency進行一個添加,因為其他的模塊要是引用這個NickNameActor他自然也會需要對Actor有依賴
關於private 和 public dependency的問題:
當這個關系只有一層時沒有任何區別

當涉及到三個模塊時,這里的依賴的public private就會起作用
頭文件內容傳遞,表示這個模塊可以調用其他模塊全部定義在在頭文件中的內容,如果有內容是 .cpp中定義,則會有無法解析的外部符號錯誤(就是將頭文件一起編譯,但是不會做鏈接,對應IncludePathModuleNames,現在基本已經棄用了)
把定義寫在頭文件中意味着他可能會被多次編譯,將拖慢編譯速度
DependencyModuleNames,則是將兩個模塊鏈接,則表示這個模塊可以調用到.cpp中定義的內容
private會切斷頭文件路徑和鏈接的傳遞,你的模塊被其他的模塊依賴時這些引入的頭的鏈接都不會傳遞
非常重要的依賴傳遞圖

當你的模塊被其他的模塊引用的時候,情況很多,上圖基本包括了所有情況

你private 引用了別的module,引用了你module的module嘗試找你的子模塊的代碼的時候就會出現文件找不到的錯誤

總結選擇:建議使用private鏈接,他們會減少編譯時間!
Implement
Implement,實現模塊


#include "Modules/ModuleManager.h" // which is in core module
IMPLEMENT_MODULE(FPlatformCommonModule, PlatformCommon)
這句話可以在你的模塊的任何地方寫,這句調用就是將你的模塊的主類給暴露給引擎
實現這個模塊的類必須繼承這個IModuleInterface的接口,一般來說做個空類就好了可以使用UE自帶FDefaultModuleImpl類
有關module的接口有很多,最基本的就加載和卸載module的生命周期


有關很少會用到的GameplayModule,游戲工程本身也是一個模塊,一般所有的模塊都是用給這個游戲模塊的,很少會反過來依賴游戲模塊

Load
LoadModule

需要選擇自己的module是在什么時候被加載的和面向什么target,通過選擇Type,最常用的是Runtime和Editor


Depend
depend
只有在依賴鏈上的模塊才會被編譯
通過添加DependencyModuleNames來配置依賴,如果沒有模塊依賴你的模塊,也可以添加Target.cs

PCH
Prcompiled Header
一般的頭文件不會自己編譯,而是在cpp引入的時候編譯
這樣的話就有一個很大的頭文件重復編譯量
讓頭文件只編譯一次
PCH定義了一個頭文件,包含了所有最常用的頭文件,然后他們會先於所有的文件編譯,他們不會重編,除非他們引入的頭文件發生了改變
必須注意的是,如果PCH重編了,所有的這個模塊的CPP文件都會重編,最好是用於引擎的頭文件或者非常少改動的頭文件

有幾種PCH,
private PCH
構建你模塊自己的PCH,把他定義在Build.cs文件里
不應該在任何頭文件或者CPP文件中引入PCH文件,他們會由UBT工具自動注入到你的模塊里
PCH是一種優化層面的東西
你的代碼寫法應該是就算PCH關掉了也能正常跑

shared PCH
除了自己定義PCH之外也可使用別人定義的PCH,模塊自己定義的SharePCH不能給自己用,只能給依賴了這個模塊的模塊使用
只有引擎模塊才能創建Share PCH
Private PCH 和 Shared PCH又是什么?有啥用?
答:它倆是特殊一點的PCH,只需記住幾(×)1(√)點,
Private PCH是給本模塊用的PCH,Shared PCH是給依賴本模塊的模塊用的PCH
一個模塊可以使用其他模塊定義的Shared PCH
一個模塊不能使用自己定義的Shared PCH
模塊對PCH的選擇只有三個:
-使用本模塊定義的Private PCH
-使用引擎自動從**本模塊依賴的模塊**定義的Shared PCH中,選出一個最佳PCH
-不使用PCH
兩者需要在模塊的build.cs文件中手動指定
UE會自動選擇最佳的SharePCH以便盡可能多的覆蓋本模塊用到的頭文件
Shared PCH的選擇范圍是本模塊依賴的模塊中定義的Shared PCH
假如模塊A依賴Slate,Core以及CoreUOject模塊,且沒定義Private PCH,
且只有Slate及Core模塊中定義了Shared PCH,
那么,A的Shared PCH就只能從Slate, Core兩個模塊中選
選哪一個呢?
基於得分來選擇——以它倆依賴的<定義了Shared PCH的>模塊數量來作為它們的分數
假設Core模塊依賴了TraceLog, Json,假如只有TraceLog模塊中定義了Shared PCH,
那么它得1分
假設Slate模塊依賴了Core, SourceControl, Json模塊,假如Json模塊中定義了Shared PCH,
那么它得2分(Core 1 + Json 1)
而且很容易看出,由於Slate的依賴項里包含了Core,那么它Shared PCH很可能包含了大部分Core模塊里的頭文件,以及其它額外的頭文件,這樣,我們就會理所當然的選擇使用Slate的Shared PCH,因為我們的模塊使用到的頭文件,也在Slate的Shared PCH里的概率更大。
因此我們將會選擇Slate模塊的Shared PCH作為本模塊的PCH。

PCH使用模式只選擇UseExplicitOrSharePCHs,這個模式下,你沒設置PCH就會使用引擎PCH,你設置了PrivatePCH就可以使用
