Hello, I am currently re-familiarizing myself with the engine and was on the same step as you. I’ve come across the same issue but the accepted answer didn’t work for me so I did something different.
- Create a Blueprint version of the camera director by right clicking the class and making a blueprint version.
- Delete the old Camera Director in the scene and replace it with the Blueprint version.
- Make sure all properties in the USTRUCT are EditAnywhere so you can access them in the editor
In my example code below I did the array challenge and gave each camera an individual blend time and time until it should change. Here is the code for reference.
.H file
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CameraDirector.generated.h"
USTRUCT()
struct FCinematicCamera
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, Category = "Cinematic")
AActor* CameraActor;
UPROPERTY(EditAnywhere, Category = "Cinematic")
float TimeBeforeChange;
UPROPERTY(EditAnywhere, Category = "Cinematic")
float blendTime;
};
UCLASS()
class INTROTOCPP_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, Category = "Cinematics")
TArray<FCinematicCamera> cameras;
float TimeToNextCameraChange;
int32 currentCamIndex = 0;
};
.CPP
#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);
TimeToNextCameraChange -= DeltaTime;
if(TimeToNextCameraChange <= 0.0f)
{
//Preforms a check to see if the array has gone out of bounds and resets it.
if (currentCamIndex == cameras.Num())
{
currentCamIndex = 0;
}
//Find the actor that handles control for the player
APlayerController* playerController = UGameplayStatics::GetPlayerController(this, 0);
//Checks that the camera array is larger than 0, we have a PC and the cameraActor is not null.
//The other properties do not need to be checked as they default to 0.0f
if(playerController && cameras.Num() > 0 && cameras[currentCamIndex].CameraActor != nullptr)
{
//Adds time to count down from each seperate camera at the current index
TimeToNextCameraChange += cameras[currentCamIndex].TimeBeforeChange;
//Does the camera blend using each cameras unique blend
playerController->SetViewTargetWithBlend(cameras[currentCamIndex].CameraActor, cameras[currentCamIndex].blendTime);
//Increments the camera index
currentCamIndex++;
}
}
}
I hope this answer helps newcomers.