包含2節(jié)視頻教程
關(guān)注3.4萬次
mari是目前為之最棒的3d材質(zhì)繪畫軟件,他支持多個繪畫通道,實(shí)時顯示法線置換貼圖,快速有效的繪畫速度,是我們選擇他的原因。
19號,也就是中國時間20日凌晨,虛幻4放出了“訂閱制”這個重磅炸彈,估計出乎大多數(shù)人的想象,已經(jīng)不止一個同事表示“自己的引擎這下沒用了”。
筆者前天搞定了付款,下載,編譯和運(yùn)行。
基本就是只要有一張visa或者M(jìn)asterCard的信用卡,官網(wǎng)www.unrealengine.com注冊一下,填寫支付信息,地址什么的隨便寫個或者硬寫中國的地址,然后去github開通一個賬號,最后在官網(wǎng)賬戶設(shè)置里把官網(wǎng)賬號和這個git賬號關(guān)聯(lián)一下,就可以從github下到代碼了。
下完后如果短時間內(nèi)不升級可以考慮退訂,這樣只是不能更新,沒有其他問題。
所以說到時候開通中國區(qū)付款后這里取消訂閱再重新訂閱就好了,辦張雙幣信用卡,不必糾結(jié)付費(fèi)的問題。
下載主要是git代碼,30兆左右,然后要按著git頁面上的提示(付費(fèi)后才可見),去release頁面下載dependencies包,總共3個:
先解壓1of2和2of2,Optional是2012編譯所需的,2013可以無視,筆者用的2013 express,就沒有試。
最后把解壓后的dependencies拷到代碼文件夾里即可。
然后運(yùn)行根目錄的bat,即可在根目錄生成2013的UE4.sln文件,如果出錯,可能是目錄沒考對,對應(yīng)提示來看看什么問題就好。
進(jìn)入后,生成配置選擇developer editor就可以開擼了,筆者的Surface Pro用了大概40分鐘才擼好,要有心理準(zhǔn)備。
如果用的是2013 Express,可能會有個atlbase.h找不到,編譯不過的問題,是因?yàn)?013本身是不帶ATL/MFC的,去官網(wǎng)下個ATL/MFC,然后在工程里設(shè)置一下ATL / MFC的頭文件和Lib路徑即可。
編譯完畢后,UE4工程設(shè)為啟動項(xiàng)目,F(xiàn)5之,啟動后可以選擇載入一些游戲模板或者建立空場景,這時候可在其他目錄里建立游戲相關(guān)的工程(游戲工程和引擎工程可以分開了,不需要再像UE3那樣綁一起了),默認(rèn)不選目錄的話會在我的文檔下開一個Unreal Projects文件夾來存工程。
新建項(xiàng)目
筆者已經(jīng)建立的項(xiàng)目
項(xiàng)目文件夾,可以跟引擎文件夾分離。
建立工程后會自動打開這個游戲工程的Sln,后面要開工的時候打開這個Sln,運(yùn)行項(xiàng)目工程(不是UE4)即可,如果不是建立新的工程的話,不需要再打開UE4.sln了。
工程文件夾里會包括一些配置、初始資源、代碼以及工程Sln,見上面的項(xiàng)目文件夾圖。
MarketPlace里有很多示例:
第一次點(diǎn)擊會提示您安裝,最好裝到個大點(diǎn)的盤,目前發(fā)現(xiàn)它這個東西下載時是會寫到安裝路徑下。幾個GB的資源,未來有可能更多,小盤的話后面杯具。官網(wǎng)有人發(fā)帖表示后面拷貝到新的路徑還得重下資源,所以爭取一步到位吧。
安裝后,第一次要下載更新包更新,這一步看人品,身邊有不少人都遇到了卡81的問題:
卡在81這里老半天,最后報個:
官網(wǎng)正在討論這個的解決方案:
https://answers.unrealengine.com/questions/14683/launcher-update-stuck-on-downloading.html
筆者自己是一直不斷關(guān)了重開,試了20幾回,不知道怎么有一次就好了……所以說很看人品……如果您也遇到了這個問題,可以多試幾次,也可以看看上面的鏈接最新到什么程度了。
好了的話,“正版用戶”就基本上可以下載了:
這個沒節(jié)操的……Bird發(fā)現(xiàn)!
盜版用戶這里怎樣我也不清楚,不過這次Epic已經(jīng)是非常有誠意了,希望大家能支持一下正版,畢竟引擎越做越好用,實(shí)際最終受益的是我們所有開發(fā)者。
初步感覺變化還是有點(diǎn)大的,后面慢慢展開,希望我能完成這個系列。
打開UE4,短暫的興奮過后,開始大概掃一掃UE4的編輯器,整個界面比UE3更有現(xiàn)代氣息:
之前看其他人寫的文章,虛幻4最重要的改動集中在下面幾個方向上:
跨平臺:
WIN和MAC平臺都能使用,這就意味著必須使用兩個平臺都能接受的方案。
界面:
由于上述的原則,WPF界面雖然很酷,不支持MONO就只能跟好評無緣了(順便吐槽一下微軟,基于NET做了那么多東西,卻總是虎頭蛇尾)。因此虛幻這回是自己搞了個界面系統(tǒng)出來……而且更喪心病狂的是這個界面可以用在游戲里……
C++化:
不知道是因?yàn)閁nreal Script在移動平臺上的性能表現(xiàn)不給力,還是因?yàn)樽约壕S護(hù)一套Script成本稍顯浪費(fèi),無論如何,UE4開始,之前負(fù)責(zé)連接工具和邏輯、內(nèi)容提供者和解決方案提供者的Unreal Script讓位給了"格式化"的C++。
這個改動并不是孤立的,相應(yīng)的,整個解決方案更明晰地劃分為了核心層、插件、邏輯層,一方面也提高了跨平臺方面的能力。
同時,圍繞著這個特性,最重要的應(yīng)該就是熱更新功能了吧?邏輯層代碼由于已經(jīng)獨(dú)立于核心層,所以C++編撰的邏輯層代碼修改,不需要退出編輯器,就可以在編輯器中自然而然地編譯并重新載入——參與過實(shí)際項(xiàng)目的戰(zhàn)友們應(yīng)該都明白這意味著什么。
另一方面來說,國內(nèi)不少戰(zhàn)友拿到這種國外的引擎往往是一種暴殄天物的用法,把這些引擎改得亂七八糟。所以筆者個人感覺Unity重新定義了國內(nèi)的引擎用法——沒代碼引擎變相的"好處"——人們不再是關(guān)注與技術(shù)細(xì)節(jié),而是關(guān)注與Workflow了,而后者才是國外引擎現(xiàn)在真正的核心和強(qiáng)大之處。筆者本人現(xiàn)在就深陷于一個由于改造了國外原本優(yōu)秀引擎而導(dǎo)致滿地大坑的項(xiàng)目中……不過想來未來會越來越好——國內(nèi)的開發(fā)者如果現(xiàn)在再準(zhǔn)備把引擎改得亂七八糟,是要被策劃和美術(shù)同學(xué)鄙視的——人家本身這么牛逼的特性,你一弄,沒了,咋回事兒?給個解釋唄?
Blue Print:
其實(shí)就是之前的Kismet的強(qiáng)化升級版,UE3單用Kismet能做出游戲,升級版的Blue Print應(yīng)該只強(qiáng)不差。
UPK:
不見了,資源單文件存儲:爭議滿滿的UPK終于離開歷史舞臺了,所有資源現(xiàn)在以.uassert的后綴名分散在Content文件夾下的各種場合。這也意味著之前資源包升級和DLC最大的一個攔路虎沒有了?碙auncher本身就做了自動更新,想來自動更新應(yīng)該是引擎本身就可以支持了吧?
大概用了用,瀏覽了一下它的一些例子,感覺都很不錯。
如果想開始制作自己的游戲的話最好先看看Content Examples:介紹虛幻4的基本特性和用法。從頭到尾瀏覽一遍基本上這個引擎的使用方法就都清楚了,未來這塊兒的工作應(yīng)該主要是美術(shù)和策劃的工作,程序大體應(yīng)該了解一下,特別是如果還沒有接觸過虛幻的同事們,這個可以讓你很快明白虛幻的整個工作流。
基本上,除了藍(lán)圖(虛幻3里KISMET的增強(qiáng)版)、地形有些變化外,其它內(nèi)容部分相對UDK并無太大變化,虛幻3玩家應(yīng)該能很快就上手。
其他例子多是一些手機(jī)版的游戲例子,不過例子不在多在完整。順便說一句,Strategy Game這個可以關(guān)注一下。當(dāng)年跟很多人爭辯說虛幻能用來做RTS沒人信,這個例子雖然不完全是一個RTS,但是基本上可以改變"虛幻只能用來做FPS和TPS"的印象了吧?
自己建立一個例子工程,隨便找了個Third Person的模板,帶BP的模板是指純Blue Print,不帶任何代碼的。筆者創(chuàng)建的是帶代碼的版本
Binaries顧名思義,這個例子最后會生成一個DLL在Binaries里,然后編輯器會重新加載這個DLL。熱更新的具體代碼還沒看,但是應(yīng)該是這個路數(shù)沒跑。
Config跟UE3的Config一樣,項(xiàng)目級別的系統(tǒng)設(shè)置,后面詳細(xì)展開,一般來說,如果要改設(shè)置的話是改這里的Config。
Content就是原來UE3的Content,美術(shù)、策劃資源全在這里,不解釋。
DerivedDataCache還不知道是做什么的,后面看看吧。
Intermediate是生成的臨時文件,包括工程、中間文件。
Saved包括一些運(yùn)行時會創(chuàng)建并維護(hù)的內(nèi)容:備份、日志、運(yùn)行期的Config,跟UE3的方法一樣:這個Config不需要去改,改動的應(yīng)該是根目錄Config下的內(nèi)容。
Source不用說就是代碼了。
會自動生成SLN,打開這個SLN就可以開工了,就像Unity會自動幫你建立一個Mono Develop工程一樣。
如前所述,虛幻引擎所使用的是C++,而不是C#、Java代碼。有人總覺得C++會導(dǎo)致虛幻上手難度變高,筆者個人感覺還好,因?yàn)槟阌玫降腃++是帶有一定限制的,這些C++類是需要考慮與引擎其它部分的關(guān)系,以及考慮與編輯器的關(guān)系的,再加上虛幻自己實(shí)現(xiàn)了垃圾回收,所以整個調(diào)用并不會比C#麻煩太多——當(dāng)然,LINQ什么的特殊語法就罷了。
生成的代碼包括:
ThirdPerson:模塊文件,似乎是定義這個DLL模塊的,追溯了一下感覺像是DLL Entry這樣的東西。
ThirdPersonCharacter:第三人稱模式下,控制器操作的對象。目前里面寫了很多跟輸入消息綁定的語句。
ThridPersonGameMode:Game Mode是UE3帶過來的概念了,當(dāng)前第三人稱游戲的一些設(shè)置,目前這里面定義了當(dāng)前游戲控制器的操作對象:
// set default pawn class to our Blueprinted character
static ConstructorHelpers::FObjectFinder<UClass> PlayerPawnBPClass(TEXT("Class'/Game/Blueprints/MyCharacter.MyCharacter_C'"));
if (PlayerPawnBPClass.Object != NULL)
{
DefaultPawnClass = PlayerPawnBPClass.Object;
}
注意這里,不是直接注冊的ThirdPersonCharacter,那ThirdPersonCharacter還有什么用?
別急,我們先看看:
Class'/Game/Blueprints/MyCharacter.MyCharacter_C'
這個意思是從Content/下的Blueprints里加載MyCharacter.MyCharacter_C,并把它認(rèn)成一個Class。
我們?nèi)ベY源里找這個BluePrint:
打開:
解釋一下就是這個BluePrint是從ThirdPersonCharacter派生的……OMG
所以,寫在ThirdPersonCharacter代碼里的那些與輸入消息的綁定才有用:因?yàn)槭沁@個MyCharacter是從這個C++腳本派生的嘛。
但是這么一來,MyCharacter一方面可以集成程序提供的基本操作方案,另一方面,策劃可以通過BluePrint為其設(shè)計一些特殊的連線流程,兩全其美。
有些東西,不想給策劃弄的,或者策劃弄不了的,比如AI底層,程序來集成就好了。想給策劃弄的,這么一來你自己Blue Print去吧。
這塊兒筆者真心給跪了。Orz
過去的UE3的Kismet也不是不能跟對象一起用,但那如果在編輯器里操作,就是得用Prefab,本身Prefab沒有任何跟代碼相關(guān)的概念,基本類似于一個各種對象放一起的大組。從某類繼承?對不起,沒這個概念。
所以UE3里,這種情況就得自己用Unreal Script寫個UC類,然后在代碼里自己手動拼各個組成組件的空間關(guān)系……加上Kismet互操作的代碼來進(jìn)行Kismet的互操作。
現(xiàn)在這Blue Print完全超越了Prefab這個概念,相當(dāng)于把原來Unreal Script的這個工作用圖形化的方式接管過來了……難怪Unreal Script被徹底拋棄。
點(diǎn)
開始運(yùn)行,享受了一番,在ThirdPersonCharacter的方法里斷點(diǎn)調(diào)試了一下,與猜測基本無差。
最牛逼的是,我們把代碼里Move Right代碼注了,
編譯,然后再跑,不關(guān)編輯器,角色的向右移動就被我們給斃掉了,只能向前沖。
這個過程稍微有點(diǎn)危險,筆者致掛一次,記得保存改動先。
還想繼續(xù)整整,到上班點(diǎn)了,最近公司工作較忙,只能先放放后面弄了。
筆者現(xiàn)在進(jìn)行的其實(shí)就是UE3以上、UE4未滿的工作:策劃通過圖表完成自己的想法。在一個老企業(yè)中推行這種其實(shí)已經(jīng)不算新,但在國內(nèi)特別是北京圈還不算非常能讓人接受的做法。希望這次UE4的出現(xiàn)能讓各位大爺們好好冷靜下來想想。不要老說"國內(nèi)這么做游戲是有理由的",我想說的是國外的游戲做的比你好,也是有理由的!
筆者有幸參與過兩個UE3項(xiàng)目,完全不同的使用方法,總共用了5、6年。引擎學(xué)習(xí)最好還是能參與項(xiàng)目,自己看的話往往容易糾結(jié)到一些細(xì)節(jié)上去,而引擎之所以是引擎,重要的恰恰是在容易被人忽視的工作流上。單從細(xì)節(jié)上看,UE3的代碼很多地方并不完美,甚至有些奇怪,但是一旦做到工作流上,就會發(fā)現(xiàn)整個UE3工作流的強(qiáng)大之處。
先回顧一下UE3系統(tǒng)的一些結(jié)構(gòu)要點(diǎn),權(quán)當(dāng)做個記錄,看看UE4在這些方面有什么不同,作為我們接下來讀碼的突破口。
如果真心想要學(xué)習(xí)這個引擎,最好還是能用它來做做項(xiàng)目,項(xiàng)目不分大小,只論完整程度,筆者短時間內(nèi)看來是沒機(jī)會了。
從UE3到UE4
1、BuildTools
UE4除了工具和插件外,本體不分工程了,UE3的核心部分最后分了Core、Engine、Editor、WinDrv、Network、Renderer等十?dāng)?shù)個工程,UE4就一個UE4工程。但工程歸工程,編譯時還是分得很開的。
而且這個工程猜測是靠BuildTools來生成出來的(一開始那個bat)?雌饋,散落在各個文件夾下的.cs文件就像CMakeList.txt那樣,它們才是整個工程的組織核心。
事實(shí)上從UE3時代,就可以完全脫離Visual Studio IDE來工作了,UE3的工程本身都已經(jīng)不再是典型的VC工程,代碼編完后,實(shí)際上最后執(zhí)行的是Build.bat、調(diào)用UnrealBuildTools.exe來編譯,所以要改工程設(shè)置,也是需要去修改UnrealBuildTools工程的。
** 估計,如果要改工程組織結(jié)構(gòu),增加文件什么的,也需要維護(hù)這個.cs文件吧。這個可能得等做做才知道了。
不過應(yīng)該可以看出來,UE4這里是為了支持項(xiàng)目和引擎分離而進(jìn)行的。
2、Core
個人觀點(diǎn),UE3的Core重點(diǎn)是下面幾個部分:
作為整個虛幻構(gòu)架基礎(chǔ)的UObject和由一大堆宏和各種Classes.h這套組織結(jié)構(gòu)反射系統(tǒng)——圍繞它的包括GC、UObject與UnrealScript的互操作性、與編輯器的互操作性、自動序列化、對象克隆等。這個非常重要,整個虛幻體系的核心就是這一套東西,如果前面不注意的話,后面遲早會在這里栽點(diǎn)跟頭。
序列化和統(tǒng)一具名訪問:ULinkLoader,起這個名字可能主要是因?yàn)榧虞d的時候,它會自動分析Object的引用鏈,并且根據(jù)需要繼續(xù)往下加載。另外,所有虛幻的Object都會有自己獨(dú)一無二的具名路徑,例如xxx.umap:persistentLevel.Pawn_0,xx.Material.Material_0,任何時候,只要使用LoadObject、FindObject并傳入這些名字,就可以訪問到對應(yīng)的對象。這個在編輯器的維護(hù)中是相當(dāng)方便的一個底層特性。甚至,這個具名路徑還可以訪問到腳本中的類、內(nèi)置模板資源等等。
MakeCommandlet和UC腳本核心:Core中間編碼了整個Unreal Script的編譯和運(yùn)行時環(huán)境。Unreal Script編譯過程中會生成相應(yīng)工程的Unreal Script/C++互操作文件:xClasses.h以及一堆自動生成的方法和調(diào)用。編譯后的結(jié)果是.u文件,其實(shí)同時就是跟.upk資源文件一樣的格式——虛幻2不清楚,但至少從虛幻3時代開始,資源和腳本就被當(dāng)作是同一個東西,腳本是可執(zhí)行的資源,資源是不可執(zhí)行的腳本。另外與此相關(guān)的就是一套調(diào)試器——很多人用了半天虛幻3卻不知道虛幻腳本是可以調(diào)試的……AutoDebug命令行或者ToggleDebugger指令搜一下,印象中調(diào)試器的核心接口是基于UDebuggerCore還是UDebuggerInterface這個類。VS裝nFringe插件后、或者自帶的UDE都可以對腳本進(jìn)行調(diào)試。
狀態(tài)機(jī):腳本的特殊語法,狀態(tài)機(jī)是在腳本類內(nèi)部的概念,每個狀態(tài)可以重載腳本類某些函數(shù)的實(shí)現(xiàn),這樣當(dāng)狀態(tài)切換到這個狀態(tài)的時候,就只是執(zhí)行狀態(tài)內(nèi)的函數(shù)而非腳本類的函數(shù)本身。Actor和Controller里大量用到。
Latent:腳本的特殊語法,基本類似于不通過連線的Kismet,latent類似于Erlang這樣的Coroutine語言,每個語句都是步驟而非過程,步驟可能會花很多幀去執(zhí)行,執(zhí)行完畢后接著進(jìn)行下個步驟,傳統(tǒng)語言的過程只能當(dāng)前幀執(zhí)行完畢。
其它就是一系列的數(shù)學(xué)庫、內(nèi)存管理、輔助函數(shù)。內(nèi)存管理比較有意思,一開始看總覺得問題較大,當(dāng)時組里的內(nèi)存專家Aman Jiang老師實(shí)際打出來報告后發(fā)現(xiàn)這塊兒管的還是很不錯的,碎片率遠(yuǎn)低于我們的預(yù)期。
3、Engine
相當(dāng)龐大的集合,個人觀點(diǎn),重點(diǎn)在于:
Actor-Component體系:組件化結(jié)構(gòu)的虛幻版,組件化現(xiàn)在應(yīng)該是大多數(shù)引擎的標(biāo)配了吧?這塊兒可以說中規(guī)中矩,主要組件還是得花心思去看看,否則極易在接口調(diào)用順序亂掉的情況下發(fā)生問題。渲染器與游戲上層邏輯通過Component來接口,提供新的渲染技術(shù)后,只需要做一個對應(yīng)的Component就可以了——SpeedTree什么的就是這么集成進(jìn)來的。
Game-Player-Controller體系:Game Mode決定了當(dāng)前關(guān)卡的游戲玩法,一個關(guān)卡可以有不同的游戲玩法——對于FPS你可以想象虛幻競技場中的很多地圖都同時支持Free for all、奪旗、Team計分。對于網(wǎng)絡(luò)游戲,你可以想象一個關(guān)卡資源可以用來做戰(zhàn)場、也可以用來做副本。Player是所有IO的總?cè)肟冢话阋粋游戲只有一個Player,就是Local Player。主機(jī)游戲可以設(shè)計同時存在兩個Player的場合,可以用分屏顯示來分離各自的IO。進(jìn)入地圖后,會針對當(dāng)前地圖生成Controller,來實(shí)際從Player截獲輸入和部分輸出操作,并真正影響到游戲中。相應(yīng)的概念還包括View(實(shí)際上的攝像機(jī))、ClientViewport(游戲和編輯器窗口)。
Controller-Pawn體系:Pawn是可以被Controller控制的東西,Controller把IO和UI消息轉(zhuǎn)化為對Pawn的操作,通知Pawn完成其功能,并把這些功能執(zhí)行過程反饋給IO和UI。在游戲中可以切換Controller內(nèi)部的不同狀態(tài),例如根據(jù)Pawn是在走還是在爬墻,把輸入消息轉(zhuǎn)化為對Pawn不同的指令。還可以切換Controller,比如進(jìn)載具了,Controller一換就Ok。甚至技能中也可以切換Controller,比較經(jīng)典的例子就是虛幻競技場3里的榴彈炮:普通架起來的狀態(tài)下打出的是一般炮彈,炮彈飛行過程中鼠標(biāo)可以一直控制其方向,右鍵可以把這個炮彈展開使其定位在空中,然后你的視角一直停留在這個炮彈上,鼠標(biāo)變成在地面選擇一個區(qū)域,火炮變成一門發(fā)射榴散彈的大殺器,把致命散彈砸向這個區(qū)域。筆者接觸過不少游戲的游戲系統(tǒng)了——不幸的是這個流程很少有系統(tǒng)能夠不加大改地實(shí)現(xiàn)。AI也是一種Controller,操縱的是Bot這個特殊的Pawn,這塊兒有興趣也可以研究一下。
World-Level-Actor體系:World里存一堆Level,Level里存一堆Actor, Build后的光照跟Level走,Level是關(guān)卡部分的資源單位。但場景圖根是World里的Hash,虛幻3里是個八叉樹實(shí)現(xiàn)。World里實(shí)現(xiàn)了基本的場景功能,角色的走跑、懸崖邊緣的檢測、走到碰撞體前被擋住、碰撞體位置變化時導(dǎo)致自己上面放置的其它碰撞體變化……你如果有自己的場景需求,可以修改World里面的這個部分。注意,在虛幻3里場景和物理雖然有關(guān),但是本質(zhì)上還是分離的,引擎提供了默認(rèn)的整合方式,但你可以在Actor里重新控制這種整合。
資源體系:沒什么好說的,Material、Texture、各種Mesh、Particle。Material連線球很贊,但是跟渲染Stage有較深的關(guān)聯(lián),筆者試圖做過一個自以為比他更好的,跟Stage可以一定程度脫耦的材質(zhì)連線球系統(tǒng)——但是最終發(fā)現(xiàn)材質(zhì)這東西根本上還是離不開渲染Stage,什么都想控制的結(jié)局一定是什么都控制不過來。
渲染體系:就不說什么了吧,Deferred Lighting的Stage體系,網(wǎng)上的文章海了去了,做圖形的這個早就拋腦后了吧。最近一兩年的版本支持了Deferred Shading。這套Stage的低端化替換還是很方便的——畢竟現(xiàn)在需要考慮到游戲可能更多是會在intel HD 3000/4000這種顯卡上跑的可能性了。
4、UnrealEd
編輯器……怎么說呢,這個沒法按體系來了,太多了,有些精品也有些糟粕,反正編輯器這東西,沒法說,需要擴(kuò)展的時候自己去改吧。
注意屬性編輯器是如何發(fā)揮反射的強(qiáng)大效力的。
有些細(xì)節(jié)問題,實(shí)際做了可能會遇到:拷貝對象時,有些屬性是引用的(一般的Object屬性不加任何描述),有些是復(fù)制的(editinlinenew、instance和duplicate),有些是舍棄的(transient)。還有就是虛幻比較喜歡用Prototype + Clone的方式來實(shí)現(xiàn)Template-Instance這種需求,典型的例子是Animation Tree和Prefab,實(shí)例都是直接從資源拷貝出來的。主要是因?yàn)閁E3的反射外圍有一個比較強(qiáng)大的Clone系統(tǒng),但是前提是您得對剛剛列舉的那些關(guān)鍵字比較熟悉,否則為這些系統(tǒng)擴(kuò)展時就比較容易遇到問題。
多說一句:編輯器選物體用的是把物體的ID渲到一張Render Target上再去這個Render Target上查找鼠標(biāo)點(diǎn)Id的做法,叫HitProxy,如果你的游戲想支持像素點(diǎn)選,可以參考這個東西,很容易就能把這個Stage集成到游戲Stage里。
5、其他工程
就沒什么好說的了:
渲染器:Renderer,DX9、DX10、DX11、OpenGL的實(shí)現(xiàn)都有,DX10只有一個版本曇花一現(xiàn)。
平臺庫:以XXXDrv為名,例如WinDrv。主要提供平臺方法,沒什么好說的。
網(wǎng)絡(luò)庫:IpDrv、Channel什么的,也沒什么好說的。
網(wǎng)游的開發(fā)者很喜歡自己構(gòu)造上層,我參與的第一個UE項(xiàng)目就是這么做的,實(shí)際上最后做出來的上層后來看來比虛幻的整個上層體系差的太遠(yuǎn)。第二個項(xiàng)目筆者就一直推動著在虛幻框架上的小修小改。最后能實(shí)現(xiàn)什么呢?能實(shí)現(xiàn)在編輯器里根服務(wù)器通信,編輯器調(diào)整完Kismet連線圖、資源、布怪點(diǎn)后,不用退出,直接就可以啟動開發(fā)服務(wù)器,然后在編輯器內(nèi)測試剛剛自己做的東西對不對,可惜因?yàn)橘Y金原因沒做下去,兩年前這個級別的工具集成,不知道有多少人做到了?至少我現(xiàn)在在這個項(xiàng)目里還沒能推廣到,也不可能推廣到那個程度(筆者鼻子翹起來了~*^_^*)。不過未來不需要再弄了——看看虛幻4的Blueprint,可以考慮這個級別的集成了。
筆者一直認(rèn)為,虛幻3強(qiáng)大的地方不在于他的圖形,而是在于這套強(qiáng)大而穩(wěn)固的結(jié)構(gòu)和迅速的工作流,而當(dāng)你握這套結(jié)構(gòu)和工作流后,筆者發(fā)現(xiàn)所有引擎在自己的面前索然無味,圖形雖然還在追求,但已經(jīng)退居次席了,而自己重新去做引擎的沖動則不斷降低,直至完全消失。
用虛幻一定要首先明白一個原則,就是這是個解決方案式引擎,不是OGRE那樣的圖形工具庫,所以你的所有改動一定要符合虛幻的基本結(jié)構(gòu)假設(shè),否則你只是在給自己找麻煩。但是,相信我,符合這些基本的結(jié)構(gòu)假設(shè)一點(diǎn)不會讓你的自由度降低,你的控制能力把控能力還是相當(dāng)強(qiáng)的——不信你看,筆者上面列舉的框架部分,有哪個是會影響你的發(fā)揮的?M——World-Actor、V——Player、C——Controller,哪一環(huán)是可以省略的?當(dāng)然,如果您的體系結(jié)構(gòu)設(shè)計的比這個還好,那真的很恭喜您了,一山更比一山高,筆者只能感嘆于自己的時運(yùn)不濟(jì)了……
這兩天還是在看例子,看幾個Blueprint的例子,順便回想一下UE3的那些事兒。最近的緊張局面可能會延續(xù)到4月中旬,屆時才有可能有更多時間來看UE4。目前感覺變化還是挺大的,不過,喜在框架方面的改動似乎很有限。
從另一個方面,也證明了UE3的這套游戲上層邏輯框架,是多么地穩(wěn)固和強(qiáng)大。
前文說到UE3開始,虛幻就使用了UnrealBuildTool(以下簡稱UBT)來編譯和生成代碼。
為什么這么做而不是使用VS是很好理解的:因?yàn)閂S跨平臺會比較麻煩。像虛幻這樣體量的工程,單為工程做一次VS配置就基本是一天的時間
而且UE4還不像UE3那樣就十幾個工程,把所有uproject都看做工程的話,得幾十了。依賴關(guān)系復(fù)雜度幾何增長,用VS的工具去維護(hù)……而且要維護(hù)各個平臺和配置……再加上維護(hù)完后Mac、Linux還得維護(hù)一遍……
但是為什么不使用成熟的CMAKE呢,私以為可能是因?yàn)閁BT里有一系列錯綜復(fù)雜的規(guī)則,用CMAKE制作出來,即便可讀性O(shè)K,調(diào)試也比較麻煩。而且CMAKE對引擎使用者提出了一定的要求,而UBT則相對簡單——只要你不糾結(jié)它如何實(shí)現(xiàn)。
官網(wǎng)的這篇文章詳細(xì)解釋了為什么要做一個Build Tool出來:
https://docs.unrealengine.com/latest/INT/Programming/UnrealBuildSystem/ProjectFileGenerator/index.html
What are the advantages of generating project files?
可以先看看UBT的基本規(guī)則:
https://docs.unrealengine.com/latest/INT/Programming/UnrealBuildSystem/index.html
目前說來,虛幻的所有代碼集中在下面幾個文件夾里:
<Root>的Source,這個文件夾里主要是引擎代碼。
其中:
Source/Runtime里主要是引擎的核心代碼。
Source/Developer里似乎主要是一些工具工程。
Source/Editor里是編輯器相關(guān)代碼。
Source/Programs里是引擎使用中需要用到的工具。比如UBT、UnrealHeaderTool、Swarm(分布式光照計算系統(tǒng))等等。
Source/ThirdParty里是各種第三方庫。
<Root>的Plugin,這個文件夾里有各式各樣的Plugin實(shí)現(xiàn)。特殊的是Plugin的組織中需要多一個uplugin,可能是Plugin下可能會有一些資源什么的吧。我們后面再來看uplugin。
<工程項(xiàng)目>的Source,如果是代碼工程的話。
UBT目前只認(rèn)這幾個文件夾,也就是說,如果你要為引擎擴(kuò)展功能,您只能在這些文件夾里創(chuàng)建自己的工程。這一點(diǎn)是在UBT里寫死的,有代碼的可以關(guān)注一下UBT工程的FindAllRulesSourceFiles這個方法。
在這些文件夾里,您可以搜索到大量的*.Build.cs文件,這些Build.cs就是虛幻的工程組織核心,基本上,每個Build文件都可以被視為一個工程文件,而Build文件所在的文件夾可以被視為此工程的根目錄。接下來,我們不妨稱這些擁有Build.cs的文件夾為工程。UBT一開始會先去找所有的Build.cs,把它們放在一起生成一個臨時的dll。然后基于它們逐個進(jìn)行一系列的代碼分析工作,最后調(diào)用命令行進(jìn)行編譯和連接過程。
對于每個工程而言,代碼一般都散落在下面幾個文件夾:
Classes:如果你在工程根目錄下寫了個Classes,就相當(dāng)于告訴UBT這些文件是要用UnrealHeaderTool來生成運(yùn)行時反射信息的。所以,這個文件夾里頭文件的寫法必須符合可反射類的寫法規(guī)范。
還記得虛幻的哪些類是可反射的嗎?對了,所有UObject的派生類包括AActor的派生類。具體是否有所驗(yàn)證還沒看,不過最好是按照這個節(jié)奏來。
規(guī)范上無非主要就是USTRUCT、UCLASS這些宏,抄幾個就能找到感覺,或者用編輯器的類生成功能也可。
看起來,虛幻引擎發(fā)布時(不是通過編譯生成,而是通過Launcher下載的那種),這些Classes文件是隨引擎發(fā)布的,方便不具備全代碼的Mod愛好者和BluePrint開發(fā)者們來制作游戲。
Public:公共頭文件,跟Classes一樣隨著引擎發(fā)布而發(fā)布,所以這里一般都是些比較開放的接口,比如模塊入口、功能核心接口什么的;旧线@些接口沒有廢話,很清晰,跟實(shí)現(xiàn)相關(guān)的細(xì)節(jié)隱藏得非常好。與Classes相同,如果你的工程里有Public,那么里面的.h就會被當(dāng)作Public來。
Private:這個文件夾似乎不是虛幻定死的,也就是似乎可以不用Private的名字,或者多來幾個文件夾什么的。除了UHT中有一段代碼與之有一定關(guān)聯(lián)之外,UBT里是完全沒有跟這個有關(guān)的東西。它里面基本上就是各種實(shí)現(xiàn)代碼,以及要在實(shí)現(xiàn)間共享的頭文件。你也可以創(chuàng)建其他類似的文件夾,只需要Build.cs里寫上相應(yīng)的文件夾名即可:
此外還有需要注意的地方是Source根目錄下的Target.cs文件,Target的最終目標(biāo)一般都是可執(zhí)行文件,可以說,Target是整個生成期的入口,生成會首先從找到Target開始,如果沒有Target或者找不到,就會直接失敗。
此外,需要注意的是,Target.cs里面寫的類的類名,必須是Target.cs的文件名加Target,例如:Sample.Target.cs,其類名必須是SampleTarget。UBT的GetTargetTypeAndRulesInstance方法里印證了這一點(diǎn)。
UBT里面還是有不少限定用法的,Target就是其中之一,虛幻是一個比較強(qiáng)調(diào)命名的引擎,改名有很多麻煩,最好是能夠一步到位。
今天抽空看了看文檔,大概跟了跟UBT的流程,明天繼續(xù)。
行文匆匆,有些不太明白的地方評論里有補(bǔ)充,現(xiàn)在這里抱歉了!
半年多沒有維護(hù)博客了,一方面是媳婦懷孕,另一方面是公司年中有一個版本……
最近閑暇時間一直在研究虛幻,目前鋪開了大概六七個原型在做,做的過程中學(xué)到了不少東西,有一些新的想法。
本來這些都是準(zhǔn)備展開來說的,但是現(xiàn)在看來,每個話題展開都是需要大把的精力,所以還是先寫到這里。有些已經(jīng)有一些結(jié)論,有些還沒有展開研究,就當(dāng)是挖個坑吧,在后面幾個月陸續(xù)填。
目前博主所用的版本是4.4,有些結(jié)論未必在未來還繼續(xù)有效,如果發(fā)現(xiàn)有變化,后面會單起博客說明的。
總論:
仍在發(fā)展中,如果是準(zhǔn)備用來做短期商業(yè)項(xiàng)目的,請合理評估風(fēng)險。用來進(jìn)行長期商業(yè)項(xiàng)目、或者覺得目前的功能已經(jīng)可用、或者以研究為目的的,可以考慮介入。
優(yōu)點(diǎn)是開發(fā)架構(gòu)和框架體系成熟,國內(nèi)策劃不做腳本不做原型的開發(fā)模式可能確實(shí)相對不易適應(yīng)。說程序用BP不習(xí)慣的恭喜您說出了一句正確的令人發(fā)指的廢話,BP是設(shè)計給策劃和關(guān)卡設(shè)計師用的,不是給你程序員用的——話說回來,也就在中國需要去把策劃的想法翻譯成代碼的程(Fan一聲)序(Yi四聲)員(Gong一聲)。
再次重申,如果您希望什么事兒都是程序給吃下來,或者您的項(xiàng)目被迫處于這種態(tài)勢,而不是由策劃負(fù)責(zé)腳本和內(nèi)容的制作,那么請出門左轉(zhuǎn),找CE、Unity(大霧)或者其它引擎,虛幻這種跟歐美式開發(fā)方式深度綁定的引擎絕對不適合您。相信我,您只是在給自己找麻煩,然后回過頭來大罵這是一個垃圾引擎——其實(shí)只是您項(xiàng)目的開發(fā)模式不是原型開發(fā)模式,僅此而已。
沒有程序基礎(chǔ)的,看幾個例子應(yīng)該也可以自己用BP動手做點(diǎn)原型了,我現(xiàn)在基本主要游戲邏輯都用BP做,C++給BP寫節(jié)點(diǎn)和第三方庫的整合插件。BP用熟悉了,比手寫代碼的開發(fā)效率高多了(編譯和部署時間、調(diào)試更直觀方便、而且本身拖圖的效率就不比手寫差太遠(yuǎn),有些情況下反而比手寫高)。
此外開放代碼,比較深坑的地方可以自己修改,也可以隨意整合各種C++庫進(jìn)來,許多細(xì)節(jié)的實(shí)現(xiàn)比較有參考意義,比如WeakPtr之類的。論壇里有許多C++庫的整合項(xiàng)目的通知,可以隨時關(guān)注。
缺點(diǎn)是上手需要一定成本,此外,平臺上不支持PSV、PS3、Xbox360這些平臺,手機(jī)平臺不完全支持,希望全機(jī)種支持的要注意,目前只能考慮Unity或者M(jìn)onoGame。
升級快一方面也是一種缺點(diǎn),舊版本還在玩得不亦樂乎,新版本又添了一堆新東西,這不,博主還在頭疼于自己擴(kuò)展的自細(xì)分地表渲染插件在4.4下表現(xiàn)超級糟糕的問題,4.5出來直接這個問題沒有了……沒~有~了~,我那廢寢忘食地搞了一個周末是圖個啥……圖~個~啥~?!……所以,換句話說,專業(yè)的事情,交給專業(yè)的團(tuán)隊(duì)去就好了。重新發(fā)明輪子這種事兒,十年前是時尚,十年后就是愚蠢了。
工程部分:
Module不能出現(xiàn)重名。
Build.cs和Build類名必須一致。
可以創(chuàng)建獨(dú)立的Win32工程了,虛幻3是獨(dú)立Exe,如果想用到虛幻的功能,要么是需要把虛幻按照dll模式編譯加載,要么是整合在整個Launcher里,虛幻4可以創(chuàng)建獨(dú)立的Win32工程,工程里可以只用到虛幻的某些個子集。具體可參考引擎Solution里的那些Win32工程,此外,早期版Win32的工程設(shè)置和后期版的Win32工程設(shè)置不完全一樣?筛鶕(jù)自己的需要選擇最合適的模式。
多個項(xiàng)目間共享的功能,最好建立plugin工程。也可以修改UBT,添加自己的文件夾。
目前沒有找到能在獨(dú)立路徑下建立plugin的途徑,似乎只能放到項(xiàng)目的Plugins文件夾里或者引擎Source下的Plugins文件夾里。
發(fā)布Plugin給發(fā)布版用,4.3似乎是需要先找到發(fā)布版的Version.h文件,用這個文件覆蓋對應(yīng)Release版本Git庫中的對應(yīng)文件,然后再編譯和發(fā)布Release。
所有虛幻的Plugin是有加載順序的,有依賴關(guān)系的插件要注意,可以通過設(shè)定Plugin的加載階段和Dependency來解決這個問題。
一個工程(Plugin或者游戲工程)里可以包括多個模塊(Module),注意最好把核心部分和編輯器部分分開,否則發(fā)布游戲時發(fā)現(xiàn)依賴了一堆不需要的庫,太浪費(fèi)了。可以理解Plugin和工程是一個打包單元,但Module是一個組織單元。
Object Core
反射實(shí)現(xiàn)很經(jīng)典,不一定優(yōu)美,但是很實(shí)用。博主之前試圖實(shí)現(xiàn)過一個C++版的反射,template絕對用得比它好(從boost mpl繼承過來的),就是因?yàn)槿绷怂莻分析代碼得到Meta數(shù)據(jù)的東西,導(dǎo)致維護(hù)Meta起來太復(fù)雜了……再次說明牛逼的技術(shù)不是在那里玩技術(shù)玩語法,而是在玩工作流……
類和模塊改名了,導(dǎo)致之前做的資源失效?Config文件中的redirector可以幫助你。
但不是萬能的,BP重命名要小心,似乎BP類名改過來了,但是里面的內(nèi)容沒有改過來……
資源更換文件夾后,本地仍然留有一個1k左右的"尾巴"?這也是redirector的"功勞"。請使用fix up清理。
虛幻的各個Ptr的實(shí)現(xiàn)很精彩。RefCount對象可走SharedPtr,此外還有WeakPtr等。
官方推薦瑣碎而單位時間比較小的異步功能,可以考慮TaskGraph。時間較長的異步功能可以自己寫Runnable。TaskGraph還沒太搞明白怎么回事。
Actor - Component
Movement拆出去了,UE3的Movement是整合在Actor體系內(nèi)的,重新實(shí)現(xiàn)不同的Movement會比較費(fèi)勁,F(xiàn)在好了,重新做一新的Movement就好,還可以在不同的工程之間重用。
Component具有父子關(guān)系了!不僅僅是SkeletalMesh對其它Component的父子關(guān)系,其它所有的Component都有父子關(guān)系了。
Actor的Tick貌似現(xiàn)在是多線程了,具體還沒有跟。
Player – Controller
輸入現(xiàn)在多了一個InputComponent,輸入消息由Controller截獲后,有可能會先發(fā)給激活的Pawn的InputComponent和其它InputComponent?梢赃\(yùn)行時動態(tài)切換輸入所操控的對象。UE3只能由PlayerController發(fā)布所有的指令消息。
Component掛接,UE3的Attach/Detach已經(jīng)改名為Register/Unregister,在Register之前,需要先把root設(shè)置好。與UE3稍微有點(diǎn)不太一樣的是,Actor沒有顯式Register接口(FinishAndRegister做了一些附加的邏輯,調(diào)用前需要先評估是不是自己需要的),Register All什么的在Component數(shù)量多的時候非常昂貴。目前對部分Component的Register操作,經(jīng)實(shí)驗(yàn)是可以使用的。
渲染核心
Renderer現(xiàn)在有兩個:ForwardShadingRenderer和DeferredShadingRenderer,4.5的變化還未跟蹤。
默認(rèn)是不開遠(yuǎn)裁剪面的,如有需求得自己主動在View里面設(shè)置遠(yuǎn)裁剪面。
雖然多線程的調(diào)用型改了,但主體流程與UE3的渲染線程模型基本沒有變化,UE3的所有渲染擴(kuò)展方式,仍然基本可用,主要需要注意的是對其他設(shè)備的向下兼容性(主要關(guān)注Shader里的那些宏即可)。
Blueprint
目前主要用來開發(fā)原型,幾個版本的細(xì)節(jié)修改還是挺多的。
總而言之,首先需要提醒的是,用BP做項(xiàng)目,目前一定要記得多備份,最好自己架SVN服務(wù)器,改一點(diǎn)測一下就上傳一次,特別是跟接口和改名相關(guān)的場合。博主為此浪費(fèi)了兩天左右的時間。
目前Blueprint創(chuàng)建的Actor基類,其基類中指定的Component是無法被子類修改的,而且其屬性無法直接作為Actor的參數(shù)來修改。解決方法是在Actor中增加對應(yīng)屬性,并在Construct圖中,修正Actor的對應(yīng)屬性。
不帶函數(shù)返回值的BP函數(shù),重載時需要在Event Graph里進(jìn)行操作。帶函數(shù)返回值的BP函數(shù),則是右鍵重載。修改函數(shù)原型時,要注意有可能會發(fā)生修改前是個右鍵函數(shù)重載,修改后是個Event圖重載。
修改與BP合作的Interface調(diào)用型的時候,BP的重載實(shí)現(xiàn)有可能會發(fā)生找不到或是其他情況,要小心,改之前記得備份。
全局方法和靜態(tài)方法怎么辦?可以做到BPFunctionLibrary里。
讀表雖然有DataTable什么的支持,但需要代碼介入,感覺不是很舒服,推薦自己整合讀表、讀文件功能到BP中,一勞永逸,代碼可以參考它Json解析和Csv解析部分。
UI
類似WPF,熟悉WPF的人應(yīng)該非常容易上手,數(shù)據(jù)綁定什么的基本都是WPF那套概念,對我這種WPF的鐵桿支持者簡直是如沐甘露。數(shù)據(jù)綁定也是那種上手很困難,但一旦上手就覺得其它所有UI系統(tǒng)都好Low啊這樣的東西……當(dāng)然,這玩意兒對性能的負(fù)面影響也是客觀存在的。一定程度下,性能跟系統(tǒng)的擴(kuò)展和方便程度成反比,永遠(yuǎn)不要想著魚與熊掌都能兼得,要能的話,早有人做出來了。
并非唯一選擇,Coherent UI什么的也有插件提供了,而且Coherent也支持Unity和CE3,商業(yè)項(xiàng)目可以考慮。
朱峰社區(qū)網(wǎng)頁版(手機(jī)掃描-分享-添加到屏幕)
朱峰社區(qū)微信公眾號(微信掃一掃-關(guān)注)
未知用戶
2005-2024 朱峰社區(qū) 版權(quán)所有 遼ICP備2021001865號-1
2005-2024 ZhuFeng Community All Rights Reserved
VIP