2. 在C++中控制相机视图
我们现在可以创建一个C++类来控制相机视图了。 在这个教程中,我们可以扩展 Actor 为新类,我们将其称之为CameraDirector。
在
CameraDirector.h
中,我们添加以下代码到 ACameraDirector 类定义的底部位置:UPROPERTY(EditAnywhere) AActor* CameraOne; UPROPERTY(EditAnywhere) AActor* CameraTwo; float TimeToNextCameraChange;
UPROPERTY 宏使得变量对 虚幻引擎 可见。 这样,当我们启动游戏或在之后的工作部分重新载入关卡或项目时,这些变量中设置的值将不会被重置。 我们还添加了 EditAnywhere 关键帧,这让我们可以在 虚幻编辑器 中设置CameraOne(相机1)和CameraTwo(相机2)。
在
CameraDirector.cpp
中,添加如下代码行到文件的顶部位置,位于其它"#include"行的正下方:#include "Kismet/GameplayStatics.h"
GameplayStatics头文件让我们可以访问一些有用的通用函数,其中一个可供我们用于本教程。 完成后,添加以下代码到 ACameraDirector::Tick 的底部位置:
const float TimeBetweenCameraChanges = 2.0f; const float SmoothBlendTime = 0.75f; TimeToNextCameraChange -= DeltaTime; if (TimeToNextCameraChange <= 0.0f) { TimeToNextCameraChange += TimeBetweenCameraChanges; //搜寻处理本地玩家控制的actor。 APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0); if (OurPlayerController) { if ((OurPlayerController->GetViewTarget() != CameraOne) && (CameraOne != nullptr)) { // 立即切换到相机1。 OurPlayerController->SetViewTarget(CameraOne); } else if ((OurPlayerController->GetViewTarget() != CameraTwo) && (CameraTwo != nullptr)) { // 平滑地混合到相机2。 OurPlayerController->SetViewTargetWithBlend(CameraTwo, SmoothBlendTime); } } }
这个代码将可以让我们每隔3秒在两个不同的相机间切换默认玩家的视图。
现在我们的代码可进行编译,我们可以返回到 虚幻编辑器 并按下 编译 按钮。
不需要其它代码了。 我们现在可以在世界中设置CameraDirector了。
MyPawn.h
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "GameFramework/Actor.h"
#include "CameraDirector.generated.h"
UCLASS()
class HOWTO_AUTOCAMERA_API ACameraDirector : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ACameraDirector();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;
UPROPERTY(EditAnywhere)
AActor* CameraOne;
UPROPERTY(EditAnywhere)
AActor* CameraTwo;
float TimeToNextCameraChange;
};
MyPawn.cpp
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "HowTo_AutoCamera.h"
#include "CameraDirector.h"
#include "Kismet/GameplayStatics.h"
// Sets default values
ACameraDirector::ACameraDirector()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void ACameraDirector::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACameraDirector::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
const float TimeBetweenCameraChanges = 2.0f;
const float SmoothBlendTime = 0.75f;
TimeToNextCameraChange -= DeltaTime;
if (TimeToNextCameraChange <= 0.0f)
{
TimeToNextCameraChange += TimeBetweenCameraChanges;
//Find the actor that handles control for the local player.
APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0);
if (OurPlayerController)
{
if ((OurPlayerController->GetViewTarget() != CameraOne) && (CameraOne != nullptr))
{
//Cut instantly to camera one.
OurPlayerController->SetViewTarget(CameraOne);
}
else if ((OurPlayerController->GetViewTarget() != CameraTwo) && (CameraTwo != nullptr))
{
//Blend smoothly to camera two.
OurPlayerController->SetViewTargetWithBlend(CameraTwo, SmoothBlendTime);
}
}
}
}