在 UE 的一个关卡中,GameMode、GameState、玩家角色(DefaultPawn)、PlayerController、PlayerState等都是必不可少的组成单位。这些单位各自的作用如下:
下面我们将以GameMode、DefaultPawn为例来介绍这些组成单位的设置与获取。
我们在C++或蓝图中创建好继承自 AGameModeBase 的类后,在 WorldSettings 界面上选择我们自定义的GameMode 即可,这样就完成了对某一关卡的 GameMode 的设置。
图1,GameMode的设置
通过 UGameplayStatics::GetGameMode() 即可获取到属于某个关卡的 GameMode。其用法示例如下,其中ACylindricalWall 是一个 Actor,我们先通过 GetGameMode() 获取到 AGameModeBase,再转换成我们自定义的 AGodGameMode。
void ACylindricalWall::MonitorPlayer()
{
// 获取GameMode
auto GameMode = Cast(UGameplayStatics::GetGameMode(this));
// ...
}
GetGameMode() 的源码实现如下,其先获取 World,再由 World 获取 GameMode。
AGameModeBase* UGameplayStatics::GetGameMode(const UObject* WorldContextObject)
{
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
return World ? World->GetAuthGameMode() : NULL;
}
2.1.1 在WorldSettings界面上设置玩家角色
玩家角色 DefaultPawn 的设置,也可以和 GameMode 一样,在 WorldSettings 界面上完成,如下图所示。但这种在 WorldSettings 界面上设置的方法只适用于 所选择的 GameMode 是蓝图类的情况下。在 GameMode 是C++类的情况下,DefaultPawnClass 的下拉框操作是禁止的。
图2,DefaultPawn的设置
2.1.2 在GameMode中设置玩家角色
为了解决刚才提出的问题——若在 WorldSettings 界面上选择的 GameMode 类是 C++类,则无法在 WorldSettings 界面上选择 DefaultPawnClass,我们可以在 GameMode 类中设置玩家角色。其设置方法如下,在 GameMode 的构造函数中,我们直接给 DefaultPawnClass 赋值,从而完成玩家角色的设置。除此之外,通过给 PlayerControllerClass 赋值,可以直接设置玩家控制器。
AGodGameMode::AGodGameMode()
{
// set default pawn class to our Blueprinted character
static ConstructorHelpers::FClassFinder PlayerPawnBPClass(TEXT("/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter"));
if (PlayerPawnBPClass.Class != NULL)
{
// 设置玩家角色
DefaultPawnClass = PlayerPawnBPClass.Class;
PlayerControllerClass = AGodPlayerController::StaticClass();
}
}
通过 UGameplayStatics::GetPlayerPawn() 即可获取到属于某个关卡的玩家角色。其用法示例如下,其中ACylindricalWall 是一个 Actor,我们先通过 GetPlayerPawn() 获取到 APawn,再转换成我们自定义的 AGodCharacter。
void ACylindricalWall::MonitorPlayer()
{
// 获取玩家角色
auto Player = Cast(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));
// ...
}
GetPlayerPawn() 的源码实现如下,其先获取 PlayerController,再由 PlayerController 获取 Pawn。
APawn* UGameplayStatics::GetPlayerPawn(const UObject* WorldContextObject, int32 PlayerIndex)
{
APlayerController* PC = GetPlayerController(WorldContextObject, PlayerIndex);
return PC ? PC->GetPawnOrSpectator() : nullptr;
}
当玩家角色是一个 Character 时,也可以使用 GetPlayerCharacter() 代替 GetPlayerPawn()。