上文我們談到了Component-Actor-Pawn-Controller的結(jié)構(gòu),追溯了AController整個家族的崛起和身負的使命。本篇我們繼續(xù)來探討Controller家族中最為人所知的PlayerController和AIController。
作為一個Controller,我們討論的依然是該如何控制。我們已經(jīng)知道了Controller可以Possess并控制Pawn,但是Controller本身又是怎么驅(qū)動起來的呢?一個游戲里的控制角色大抵都可以分為兩類:玩家和AI。不管是單機游戲或者分屏多玩家,還是網(wǎng)絡(luò)玩家聯(lián)機對戰(zhàn),游戲都是為了玩家服務(wù)的,所以也必然會有一個或多個玩家,就算是如《山》那種純看的游戲,也是有一個“可觀察不可動”的玩家的。而AI的實體的數(shù)量就可以是零或者多個。
Note1:依舊重申:輸入、網(wǎng)絡(luò)、AI行為樹等模塊雖跟PlayerController和AIController關(guān)系緊密,但目前都暫且不討論,留待各自模塊章節(jié)再敘述。

APlayerController

讓咱們先從簡單的單機游戲開始討論吧,比如一款單機FPS游戲,這個游戲里已經(jīng)用各種各樣的Actor們構(gòu)建完成了世界場景,你的主角和敵人Pawn們也都在整裝待發(fā),這個時候你思考這么一個問題,我該怎么玩這個游戲?壯麗的舞臺已經(jīng)準備好了,就等你入場了。先拋開具體的引擎而言,首先你需要能看見(擁有Camera和位置),其次你必須能響應(yīng)輸入(玩家按WASD你應(yīng)該能接收到),然后你可以根據(jù)輸入操控一些Pawn(Possess然后傳遞Input),這樣一個單機游戲中的簡單玩家控制器就差不多了。一個游戲中只有一個PlayerController,在不同的關(guān)卡中你可以使用不同的PlayerController,但是同一時刻響應(yīng)的只能是一個PlayerController。
插上多個手柄,咱們再拓展一下,比如像《街霸》那種單PC但是多玩家對抗或者協(xié)作的游戲。兩個玩家可以分別用兩個手柄,或者一個用鍵盤一個用鼠標,甚至是鍵盤上的不同區(qū)域,形式可以多種多樣。這個時候如果依然只有一個PlayerController,實現(xiàn)起來其實也是可行的,把兩個手柄——所有的輸入都由這個PlayerController來接收,然后在PlayerController內(nèi)部再分別根據(jù)情況去處理不同的Pawn。但是這種方式的缺點顯然也在于很容易把玩家1、2的輸入和控制混雜在一起,沒有清晰的區(qū)分開。因此,為了支持這種情況,我們可以開始允許游戲中同時出現(xiàn)多個PlayerController,每個PlayerController甚至都可以擁有自己的Viewport(分屏或者不同窗口),這樣我們通過配置,可以精確的路由手柄1的輸入給玩家1,各自的邏輯也很好的區(qū)分和復用。
再插上網(wǎng)線繼續(xù),到了網(wǎng)游時代,我們的游戲就開始允許有多人聯(lián)機對戰(zhàn)了。玩家在自己的PC上控制的只是自己的本地的角色,而屏幕游戲里其他的玩家角色是由網(wǎng)線另一端的玩家控制的。為了更好的適應(yīng)這種情況,我們就又得擴展一下PlayerController的概念,PlayerController不僅能控制本地的Pawn,而且還能“控制”遠程的Pawn(實際上是通過Server上的PlayerController控制Server上的Pawn,然后再復制到遠程機器上的Pawn實現(xiàn)的)。
因此我們來看看UE里的PlayerController:

PlayerController因為是直接跟玩家打交道的邏輯類,因此是UE里使用最多的類之一。UE4.13.2版本里1632行的.h文件和4686行的.cpp文件,里面實現(xiàn)了很多的功能,初閱讀起來往往深陷其中不得要領(lǐng)。但是在上述的分析了之后,我們也可以在其中大概歸納出幾個模塊: