# 一、序言
我们知道每一个大型的游戏引擎,都有一个属于他们自己的架构,虚幻引擎也不例外。游戏由 GameMode
和 GameState
组成。加入游戏的人类玩家与 PlayerControllers
相关联。这些 PlayerController
允许玩家在游戏中拥有棋子,以便他们可以在关卡中拥有物理表示。 PlayerControllers
还为玩家提供输入控件、平视显示器或 HUD
,以及用于处理摄像机视图的 PlayerCameraManager
。
# 二、框架基础 GameMode
GameMode
设定了游戏的规则,其中包括:
- 出现的玩家和观众数量,以及允许的玩家和观众最大数量。
- 玩家进入游戏的方式,可包含选择生成地点和其他生成 / 重生成行为的规则。
- 游戏是否可以暂停,以及如何处理游戏暂停。
- 关卡之间的过渡,包括游戏是否以动画模式开场。
基于规则的事件在游戏中发生,需要进行追踪并和所有玩家共享时,信息将通过 Game State
进行存储和同步。这些信息包括:
- 游戏已运行的时间(包括本地玩家加入前的运行时间)。
- 每个个体玩家加入游戏的时间和玩家的当前状态。
- 当前
Game Mode
的基类。 - 游戏是否已开始
正因为 GameMode
提供了游戏所需要的规则,所以它只存在于服务器上,客户端是没有的。
# 三、游戏状态 GameState
游戏玩家的状态,例如人类玩家或模拟玩家的机器人。作为游戏的一部分而存在的非玩家 AI 将不会拥有玩家状态。在玩家状态中适当的示例数据包括玩家姓名或得分、比赛中 MOBA 等的等级,或玩家当前是否在 CTF 游戏中携带旗帜。所有玩家的玩家状态存在于所有机器上(与玩家控制器不同),并且可以自由复制以保持同步。其中包括:
- 已经连接的玩家列表情况。
- 玩家团队得分情况。
- 开放世界中已经完成的游戏任务。
Game State
负责启用客户端监控游戏状态。从概念上而言, Game State
应该管理所有已连接客户端已知的信息(特定于 Game Mode
但不特定于任何个体玩家)。它能够追踪游戏层面的属性,如已连接玩家的列表、夺旗游戏中的团队得分、开放世界游戏中已完成的任务,等等。
Game State
并非追踪玩家特有内容(如夺旗比赛中特定玩家为团队获得的分数)的最佳之处,因为它们由 Player State
更清晰地处理。整体而言, GameState
应该追踪游戏进程中变化的属性。这些属性与所有人皆相关,且所有人可见。 Game mode
只存在于服务器上,而 Game State
存在于服务器上且会被复制到所有客户端,保持所有已连接机器的游戏进程更新。
# 四、玩家控制器( PlayerController
和 AIController
)
控制器是非物理 Actor
,可以拥有一个 Pawn
(或 Pawn
派生类,如 Character
)来控制其动作。人类玩家使用 PlayerController
来控制 Pawn,而 AIController
为他们控制的 Pawn
实现人工智能。控制器通过 Possess
函数控制 Pawn
,并通过 Unpossess
函数放弃对 Pawn
的控制。
控制器接收他们控制的 Pawn
发生的许多事件的通知。这使 Controller
有机会实现响应此事件的行为,拦截事件并取代 Pawn
的默认行为。可以在给定 Pawn
之前使 Controller
滴答作响,从而最大限度地减少输入处理和 Pawn
移动之间的延迟。
默认情况下, Controllers
和 Pawns
之间是一对一的关系;意思是,每个控制器在任何给定时间只控制一个 Pawn
。这对于大多数类型的游戏来说是可以接受的,但可能需要进行调整,因为某些类型的游戏 —— 想到实时策略 —— 可能需要同时控制多个实体的能力。
# 五、用户界面和 HUD
用户界面是指菜单和其他交互元素。这些元素通常像 HUD
一样叠加在屏幕上绘制,但在某些情况下,它们可能是游戏世界本身的一部分,渲染到世界表面上。最明显的 UI 示例是游戏启动时显示的主菜单或玩家暂停游戏时显示的暂停菜单。但是,在播放过程中可能会显示其他 UI。这些可用于在游戏中或更复杂的情况下(例如在 RTS
或 RPG
中)显示角色之间的对话,它们可能是游戏本身不可或缺的一部分,允许玩家选择武器、盔甲、要建造的单位等。
HUD
是指在游戏过程中覆盖在屏幕上的状态和信息。 HUD
的目的是告知玩家游戏的当前状态,即分数、他们的健康状况、剩余时间。
通俗来说,我们在游戏中看到的图片,文字,按钮都可以说是用户界面,能被肉眼看到的界面都可以说是用户界面。
# 六、相机管理者 PlayerCameraManager
PlayerCameraManager
类是一个相机管理器。默认情况下,它自己的内置行为是在挂起的视图目标和由控制台命令触发的调试摄像机之间混合。否则,它会向 ViewTarget
查询相机视点的操作以及所有其他相机设置。通常您不需要 PlayerCameraManager
子类 - 如果自动规则不足,除了可能添加用于设置 ViewTarget
的规则之外,需要对 PlayerCameraManager
进行少量修改。所有相机的属性和行为都在 CameraComponent
中设置,该类 Camera Actor
主要用作 CameraComponent
的包装器,因此可以将相机直接放置在关卡中,而不是放在另一个类中。
在 CameraComponent
中,可以设置相机是透视模式还是正交模式。可以为透视模式设置垂直视野 ( FOV
),可以为正交模式设置世界单位的宽度。对于这两种模式,都可以指定纵横比,并为常用设备和显示器类型预设纵横比
后期处理效果可以添加到相机,也可以缩放后期处理效果的强度。
将两个组件添加到 CameraComponent
以帮助在编辑器中进行视觉放置,尽管它们在游戏过程中不可见。 FrustumComponent
显示相机视野的位置。默认情况下不显示,但可以通过在视口中选择 Show > Advanced > Camera Frustums
来打开。 StaticMeshComponent
表示相机在关卡中的位置。
# 七、 Actor
类
Actor
使我们在虚幻里最常用的类, Actor
是可以放置到关卡中的任何对象,例如相机、静态网格物体或玩家起始位置。 Actor
支持 3D 变换,例如平移、旋转和缩放。它们可以通过游戏代码(C++ 或蓝图)创建(生成)和销毁。它可以挂上组件,使得它的灵活性和功能性更加的丰富和强大。 Actor
支持具有 SceneComponent
的层次结构。每个 Actor
还具有一个 RootComponent
属性,用于指定哪个组件充当 Actor
的根。 Actor
本身没有变换,因此没有位置、旋转或缩放。相反,它们依赖于组件的转换;更具体地说,它们的根组件。如果此 Component
是 SceneComponent
,它会为 Actor
提供转换信息。否则, Actor
将没有变换。其他附加组件具有相对于它们附加到的组件的变换。
综上所述,虚幻的引擎架构是基于以上的几点来进行拓展和延伸,每一个类都有自己的功能和特点,相辅相成,相互依赖,缺一不可。