我们在平时开发中,少不了编写一些逻辑去控制相机,例如俯视角镜头与各个特写镜头的过渡切换,因此了解一些PlayerCameraManager是有必要的。
PlayerCameraManager是UE自带的相机管理组件,本身比较简单,一般需要自行扩展。本文就来简单讲解一下。
1.PlayerCameraManager执行流程
执行流程如下图所示:
游戏启动后通过GameMode找到PlayerController,PlayerController的蓝图面板中也可以指定当前的PlayerCameraManager类是哪一个,然后通过PlayerController创建PlayerCameraManager,在其更新时可以通过蓝图方法重写BlueprintUpdateCamera函数,若不重写则通过UE自己的逻辑执行更新,输出完的结果还会通过CameraModifier再执行一次最终修改,然后输出。
2.重写PlayerCameraManager类,以便扩展
我们可以蓝图中指定PlayerCameraManager的类,首先创建一个继承PlayerCameraManager的蓝图:
然后找到PlayerController,设置自定义的相机管理器类:
这一步在c++部分对应代码如下(SpawnPlayerCameraManager函数)
PlayerController.cpp:
void APlayerController::PostSeamlessTravel()
{
// Track the last completed seamless travel for the player
LastCompletedSeamlessTravelCount = SeamlessTravelCount;
CleanUpAudioComponents();
if (PlayerCameraManager == nullptr)
{
SpawnPlayerCameraManager();
}
}
void APlayerController::SpawnPlayerCameraManager()
{
// servers and owning clients get cameras
// If no archetype specified, spawn an Engine.PlayerCameraManager. NOTE all games should specify an archetype.
FActorSpawnParameters SpawnInfo;
SpawnInfo.Owner = this;
SpawnInfo.Instigator = GetInstigator();
SpawnInfo.ObjectFlags |= RF_Transient; // We never want to save camera managers into a map
if (PlayerCameraManagerClass != NULL)
{
PlayerCameraManager = GetWorld()->SpawnActor<APlayerCameraManager>(PlayerCameraManagerClass, SpawnInfo);
}
else
{
PlayerCameraManager = GetWorld()->SpawnActor<APlayerCameraManager>(SpawnInfo);
}
if (PlayerCameraManager != NULL)
{
PlayerCameraManager->InitializeFor(this);
}
else
{
UE_LOG(LogPlayerController, Log, TEXT("Couldn't Spawn PlayerCameraManager for Player!!") );
}
}
3.通过BlueprintUpdateCamera自定义更新逻辑
PlayerCameraManager中预留了自定义更新的函数BlueprintUpdateCamera,我们可以在自定义相机管理器蓝图类中重写它:
该函数对应c++部分如下:
void APlayerCameraManager::UpdateViewTargetInternal(FTViewTarget& OutVT, float DeltaTime)
{
if (OutVT.Target)
{
FVector OutLocation;
FRotator OutRotation;
float OutFOV;
if (BlueprintUpdateCamera(OutVT.Target, OutLocation, OutRotation, OutFOV))
{
OutVT.POV.Location = OutLocation;
OutVT.POV.Rotation = OutRotation;
OutVT.POV.FOV = OutFOV;
}
else
{
OutVT.Target->CalcCamera(DeltaTime, OutVT.POV);
}
}
}
4.关于CameraModifier
最后再讲一下CameraModifier,在相机管理器更新函数的末尾处还会遍历所有已添加的CameraModifier,更新相机位置信息:
if (!bDoNotApplyModifiers || bAlwaysApplyModifiers)
{
// Apply camera modifiers at the end (view shakes for example)
ApplyCameraModifiers(DeltaTime, OutVT.POV);
}
例如CameraShake就是一种CameraModifier,我们也可以新建一个继承CameraModifier的蓝图类:
并通过蓝图节点Add New Camera Modifier添加修改器:
对PlayerCameraManager的简单讲解到此结束,本文的内容可以应对简单相机扩展与使用。