参考链接
CameraDirctor.h
#define CameraDirctor.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CameraDirector.generated.h"
UCLASS()
class QUICKSTART_API ACameraDirector : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ACameraDirector();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere)//设置为在任何地方都可以编辑,VisableAnywhere是在任何地方都可以查看
AActor* CameraOne;//指向一个摄像机
UPROPERTY(EditAnywhere)//设置为在任何地方都可以编辑
AActor* CameraTwo;//指向一个摄像机
float TimeToNextCameraChange;//切换摄像机视角的时间,初始值为0
};
CameraDirctor.cpp
#define CameraDirctor.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#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)
{
//DeltaTime为每帧的时间,用下面语句设置后,假如你1s60fps,那么就调用60次Tick()
Super::Tick(DeltaTime);
//摄像机停留时间
const float TimeBetweenCameraChanges = 2.0f;
//平滑过渡时间
const float SmoothBlendTime = 0.75f;
//DeltaTime = 1秒 / 帧数 得到的就是每一帧的时间
//假设这里DeltaTime = 1s / 60fps = 0.016s/fps
TimeToNextCameraChange -= DeltaTime;
//TimeToNextCameraChange初值为0,DeltaTime为0.016
if (TimeToNextCameraChange <= 0.0f)
{
TimeToNextCameraChange += TimeBetweenCameraChanges;
// 查找处理本地玩家控制的actor。
//Player0是本地玩家的控制器
//在此获取到控制器
APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0);
if (OurPlayerController)
{
if ((OurPlayerController->GetViewTarget() != CameraOne) && (CameraOne != nullptr))//判断当前控制器控制的是否是摄像机1,不是的话就立即切到摄像机1
{
// 立即切换到摄像机1。
OurPlayerController->SetViewTarget(CameraOne);
}
else if ((OurPlayerController->GetViewTarget() != CameraTwo) && (CameraTwo != nullptr))//判断当前控制器控制的是否是摄像机1,不是的话就平滑切到摄像机1
{
// 平滑地混合到摄像机2。
//这是个平滑切换摄像头的接口
OurPlayerController->SetViewTargetWithBlend(CameraTwo, SmoothBlendTime);
//OurPlayerController->SetViewTargetWithBlend(CameraTwo, SmoothBlendTime,EViewTargetBlendFunction::VTBlend_Cubic);也行,默认是EViewTargetBlendFunction::VTBlend_Linear
}
}
}
}
在编写完代码以后,将该类拖入视口,并且在世界大纲里面找到这个类,设置一下CameraOne和CameraTwo即可。
代码逻辑
在切换摄像机视角的时候,官方所使用的代码比较巧妙,但是逻辑并不复杂,我在此简单说明。
TimeToNextCameraChange初值为0。在程序刚开始以后,减去一帧的时间成为负数,进入if语句。
进入if语句以后,修改了一下TimeToNextCameraChange,为其增加了一个"摄像机停留时间"
TimeToNextCameraChange += TimeBetweenCameraChanges;
那么,需要过去TimeBetweenCameraChanges这么久的时间,调用了TimeBetweenCameraChanges*帧数次的Tick(),TimeToNextCameraChange就会再次变成负数,进入if语句,切换摄像头