简述
PlayerController就是交由玩家控制。AIController就是系统控制。
APlayerController
功能介绍
-
Camera的管理,目的都是为了控制玩家的视角,所以有了PlayerCameraManager这一个关联很紧密的摄像机管理类,用来方便的切换摄像机。PlayerController的ControlRotation、ViewTarget等也都是为了更新Camera的位置。因为跟Camera的关系紧密,而Camera最后输出的是屏幕坐标里的图像,所以为了方便一些拾取的HitResult函数也都是实现在这里面。
-
Input系统,包括构建InputStack用来路由输入事件,也包括了自己对输入事件的处理。所以包含了UPlayerInput来委托处理。
-
UPlayer关联,既然顾名思义是PlayerController,那自然要和Player对应起来,这也是PlayerController最核心的部分。一个UPlayer可以是本地的LocalPlayer,也可以是一个网络控制UNetConnection。PlayerController只有在SetPlayer之后,才可以开始正常工作。
-
HUD显示,用于在当前控制器的摄像机面前一直显示一些UI,这是从UE3迁移过来的组件,现在用UMG的比较多,等介绍UI模块的时候再详细介绍。
-
Level的切换,PlayerController作为网络里通道,在一起进行Level Travelling的时候,也都是先通过PlayerController来进行RPC调用,然后由PlayerController来转发到自己World中来实际进行。
-
Voice,也是为了方便网络中语音聊天的一些控制函数。
回想我们写过的游戏,往往也有一个Player类(一般是单件或者全局变量)?里面几乎是放着所有跟该玩家相关的业务逻辑代码。UE里的PlayerController就是这种概念,优点当然是直接方便好理解,缺点也如你所见,会代码膨胀得比较快。不过目前来说还算能接受,等某一块功能真的比较大了之后,可以再把它抽出一个单独的类来,如PlayerInput和PlayerCameraManager一样。
哪些逻辑应该放在PlayerController中?
PlayerController里的成员的意义在于更好的实现控制。比如假设玩家在一个关卡内可以按AABB来作弊获得100金币,但是限最多3次。那么这个按键的响应就应该由PlayerController来接收,然后调用AddCoin(100),并更新PlayerController里的成员变量CoinCheatCount。也或者想实现马里奥的加速跑,也可以在PlayerController里增加Speed的成员变量。
Tip
-
记住PlayerController是可被替换的,不同的关卡里也可能是不一样的。
-
PlayerController也不一定存在,考虑一下如果把马里奥做成联机游戏,那么对方玩家被同步过来的将只有PlayerState,对方玩家的PlayerController只在服务器上存在。所以这个时候,如果你把金币数据放在PlayerController里的话就非常尴尬了。所以为了扩展性来说,还是根据职责分明的原则来正确划分业务逻辑会比较好。
-
在任一刻,Player:PlayerController:PlayerState是1:1:1的关系。但是PlayerController可以有多个备选用来切换,PlayerState也可以相应多个切换。
AIController
从某种程度上来说,AI也可以算是一个Player,只不过它不需要接收玩家的控制,可以自行决策行动。从玩家控制的逻辑需要有一个载体一样,AI的逻辑算法也需要有一个运行的实体。而这就是UE里的AIController:
-
Navigation,用于智能根据导航寻路,其中我们常用的MoveTo接口就是做这件事情的。而在移动的过程中,因为少了玩家控制的来转向,所以多了一个SetFocus来控制当前的Pawn视角朝向哪个位置。
-
AI组件,运行启动行为树,使用黑板数据,探索周围环境,以后如果有别的AI算法方法实现成组件,也应该在本组件内组合启动。
-
Task系统,让AI去完成一些任务,也是实现GameplayAbilities系统的一个接口。目前简单来说GameplayAbilities是为Actor添加额外能力属性集合的一个模块,比如HP,MP等。其中的GamePlayEffect也是用来实现Buffer的工具。另外GamePlayTags也是用来给Actor添加标签标记来表明状态的一种机制。目前来说该两个模块似乎都是由Epic的Game Team在维护,所以完成度不是非常的高,用的时候也往往需要根据自己情况去重构调整。
同PlayerController一样,AIController也只存在于Server上(单机游戏也可看作是Server)。游戏里必须有玩家参与,而AI可以没有,所以AIController并不一定会存在。我们可以在Pawn上配置AIControllerClass来让该Pawn产生的时候自动为它分配一个AIController,之后自动释放。
哪些逻辑应该放在AIController中?
AIController都是在关卡内比较临时存在的,比如小怪之类的。