tl;dr : Is it possible to edit the members of an array that consists structs?
Hello there,
I’m fairly new to Unreal Engine so to get started I started checking out the C++ Programming Tutorials on the docs.
I’m Currently in Game-Controlled Cameras tutorial doing the 4th part, which is an exercise basically asking you this at some point
Instead of using Actor pointers to store your cameras, create a Structure that holds the pointer, as well as time before changing the view, and blend time to the new view.
So I went ahead writing the code
#pragma once
#include "GameFramework/Actor.h"
#include "CameraDirector.generated.h"
USTRUCT()
struct FCameraStruct
{
GENERATED_USTRUCT_BODY();
UPROPERTY(EditAnywhere)
AActor* Camera;
AActor* GetCamera()
{
return Camera;
}
bool isActorValid() const
{
if (!Camera) return false;
return Camera->IsValidLowLevel();
}
FCameraStruct()
{
Camera = NULL;
}
};
UCLASS()
class GETTINGSTARTED_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)
TArray<FCameraStruct> Cameras;
UPROPERTY(EditAnywhere)
float TimeToNextCameraChange = 5.0f;
};
In the Unreal Editor my properties look like this :
And I cannot edit the members of the Cameras array just add , delete or duplicate the members.
My Question is, how can I edit the struct of each array member in the Editor? Or am I limited doing it only through hard coding in C++ / Creating Blueprint Struct?
Hello,
I don’t know if you are still looking for the answer to the question but I will post it here in case someone ends up having this problem again
I ran into the same problem and I managed to solve it by adding USTRUCT(BlueprintType) before the struct declaration.
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++;
}
}
}