想象兔子与蜗牛比赛。游戏框架的基础是GameMode。GameMode设置了游戏的规则,比如“最先经过终点的玩家获胜”,他也处理players的生成。
Player在PlayerController中设置,PlayerController可以拥有一个Pawn,Pawn是一个游戏中Player可操作的对象(物理上的代表),当Controller拥有这个Pawn,并且可以为其行为设置规则。在我们的例子中,将有两个Pawn,一个是蜗牛,一个是兔子。兔子将设置为Character类(Pawn的一个特殊子类),Character中有已经封装好的移动功能组件Character Movement Component,包含跑跳等常规动作。因为蜗牛有区别有兔子的运动风格,所以他从pawn类直接继承。
你可以在Pawn中设计自己的移动逻辑或其他游戏逻辑,这些功能也可以在Controller中设计。一个Controller可以是从人类玩家获得输入的PlayerController,也可以是由电脑自动控制的AIController。在这个例子中,玩家将会控制蜗牛,所以PlayerController控制蜗牛Pawn。AI控制兔子,AIController持有兔子这个角色并且在之中设置了何时他应该停止,冲刺以及瞌睡的游戏逻辑。只有人类玩家关心由摄像机提供的视角,所以只有蜗牛Pawn中的一个Camera Component会被使用。
在游戏过程中,来自玩家的输入将会移动蜗牛,HUD重叠在摄像机提供的视角上,显示当前排名以及花费的比赛时间。
1、使用玩家输入或者AI逻辑控制Pawns
2、代表世界的玩家、朋友、敌人
3、向玩家展现信息
4、设置与追踪游戏的规则
5、框架类之间关系
有两个主要类别处理有关正在玩的游戏的信息:Game Mode和Game State。
即使是最开放的游戏也有规则,这些规则构成了Game Mode。在最基本的层面上,这些规则包括:
当游戏中与规则相关的事件发生并需要跟踪并与所有玩家共享时,该信息将通过Game State进行存储和同步。这些信息包括:
Game Modes
虽然某些基本要素,比如需要玩的玩家数量,或者这些玩家加入游戏的方法,对于许多类型的游戏来说都是常见的,根据正在开发的特定游戏,可以实现无限的规则变化。无论这些规则是什么,Game Modes都旨在定义和实现它们。目前有两种常用的Game Modes基类。
引擎版本4.14引入AGameModeBase,它是所有Game Modes的基类,AGameModeBase是经典简化版本AGameMode。AGameMode是版本4.14之前的游戏模式基类仍然存在并且像以前一样运行,但现在是AGameModeBase的一个子类。AGameMode由于其实现了匹配状态的概念,因此更适合标准游戏类型,如多人射击游戏。AGameModeBase是新代码项目中包含的新默认游戏模式,因为它简单而有效。
AGameModeBase
所有Game Modes都是AGameModeBase子类,其中包含可以覆盖的相当多的基本功能。一些常见功能包括:
函数/事件 |
目的 |
InitGame (初始化游戏) |
InitGame事件在任何其他脚本之前调用(包括PreInitializeComponents),并且通过AGameModeBase初始化参数和生产其辅助类。 这是在任何Actor运行PreInitializeComponents之前调用的,包括Game Mode实例本身。 |
PreLogin (预登陆) |
接受或拒绝尝试加入服务器的玩家。Login函数设置ErrorMessage为非空字符串,则导致该函数失败。PreLogin在Login之前调用,并且在调用Login之前可能会经过大量时间,特别是如果加入的玩家需要下载游戏内容。 |
PostLogin (处理登陆) |
成功登录后调用。这是第一个可以安全地在PlayerController调用复制函数的地方。OnPostLogin可以在Blueprint中实现以添加额外的逻辑。 |
HandleStartingNewPlayer (处理启动的新玩家) |
在PostLogin或者无缝旅行之后调用,可以在蓝图中覆盖,以改变新玩家的情况。默认情况下,它会为玩家创建一个pawn。 |
RestartPlayer (重新启动玩家) |
被调用来开始产生一个玩家的Pawn。如果你想命令Pawn将在哪里生产同样有有RestartPlayerAtPlayerStart和RestartPlayerAtTransform可用。OnRestartPlayer可以在Blueprint中实现在函数结束后添加逻辑。 |
SpawnDefaultPawnAtTransform (在指定transform生产默认Pawn) |
这实际上产生了玩家的Pawn,并且可以在蓝图中被覆盖。 |
Logout (登出) |
当玩家离开游戏或被摧毁时调用。OnLogout可以实现蓝图逻辑。 |
AGameModeBase可以为游戏每种比赛形式,任务类型或特殊区域创建该类的子类。游戏可以具有任意数量的游戏模式,因此可以具有AGameModeBase该类的子类; 但是,在任何给定时间只能使用一种游戏模式。每次通过该UGameEngine::LoadMap()函数初始化关卡以进行游戏时,都会实例化Game Mode Actor 。
Game Mode不会复制到任何加入多人游戏的远程客户端; 它只存在于服务器上,因此本地客户端可以看到所使用的游戏模式类(或蓝图),但无法访问实际实例并检查其变量以查看游戏进展时发生的变化。如果玩家确实需要与当前游戏模式相关的最新信息,则该信息通过存储在AGameStateBase Actor 上保持同步,这将与游戏模式一起创建,然后复制到所有远程客户端。
AGameMode
AGameMode是AGameModeBase一个子类,有一些额外的功能来支持多人匹配和遗留行为。所有新创建的项目都默认使用AGameModeBase,但如果需要此额外行为,则可以切换到继承AGameMode。如果继承AGameMode,则还应继承游戏状态AGameState,这也支持匹配状态机。
AGameMode包含一个跟踪匹配状态或一般游戏流程的状态机。要查询目前的状态,您可以使用GetMatchState,或像HasMatchStarted,IsMatchInProgress和HasMatchEnded包装。以下是可能的匹配状态:
匹配状态几乎总是处在InProgress因为这是BeginPlay被调用的状态,并且actors开始每帧更新的时候。然而,个别游戏可以覆盖这些状态的行为以构建具有更复杂规则的多人游戏,例如允许玩家在等待其他玩家加入多人射击游戏时自由地飞行。
GameMode Blueprints 游戏模式蓝图
可以创建从Game Mode类派生的蓝图,并将它们用作项目或关卡的默认Game Mode。
从Game Mode派生的BP可以设置以下默认值:
此外,Game Modes蓝图非常有用,因为它们可以在不改变代码的情况下调整变量,因此可以用于使单个Game Mode适应多个不同关卡,而无需使用硬编码资产引用或需要工程支持和代码更改每一次调整。
Setting the Game Mode 设置游戏模式
有几种方法可以为一个关卡设置游戏模式,从最低优先级到最高优先级排序:
[/Script/EngineSettings.GameMapsSettings]
GlobalDefaultGameMode="/Script/MyGame.MyGameGameMode"
GlobalDefaultServerGameMode="/Script/MyGame.MyGameGameMode"
转存失败重新上传取消
UE4Editor.exe /Game/Maps/MyMap?game=MyGameMode -game
[/Script/EngineSettings.GameMapsSettings]
+GameModeMapPrefixes=(Name="DM",GameMode="/Script/UnrealTournament.UTDMGameMode")
+GameModeClassAliases=(Name="DM",GameMode="/Script/UnrealTournament.UTDMGameMode")
Game State游戏状态
该Game State是负责使客户能够监视游戏的状态。从概念上讲,Game State应该管理想让所有连接的客户端知道的信息,并且特定于Game Mode,但不是特定于任何单个玩家。它可以跟踪游戏范围内的属性。(例如连接的玩家列表,Capture The Flag游戏中的队伍得分,在开放世界游戏中完成的任务,等等)
Game State不是追踪玩家特定事物的最佳位置,例如特定玩家在Capture The Flag比赛中为球队得分的数量,因为Player State可以更清晰地处理。通常,GameState应该跟踪在游戏过程中发生变化的属性,并且对每个人都是相关且可见的。虽然Game Mode仅存在于服务器上,但Game State存在于服务器上并被复制到所有客户端,随着游戏的进行使所有连接的计算机保持最新状态。
AGameStateBase是基本实现,它的一些默认功能包括:
功能或变量 |
使用 |
GetServerWorldTimeSeconds (获取服务器世界时间) |
这是服务器的UWorld功能版本,GetTimeSeconds将在客户端和服务器上同步,因此可以用于复制。 |
PlayerArray (玩家数组) |
这是所有APlayerState对象的数组,为游戏中的所有玩家做某事时非常有用。 |
HasBegunPlay (是否开始游玩) |
如果BeginPlay已在游戏中的actor上调用该函数,则返回true 。 |
AGameStateBase通常在C ++或蓝图中进行扩展,以包含让玩家了解游戏中发生的事情所需的其他变量和函数。所做的具体修改通常基于制作游戏状态的配对游戏模式。游戏模式本身也可以将其默认的游戏状态类型覆盖为任何C ++类或派生自的蓝图AGameStateBase。