USTRUCT() members in Editor.

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 :

http://puu.sh/ujRfR/123fe3354c.png

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?

Thanks in advance!

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.


    USTRUCT(BlueprintType) 
    struct FMyStruct {...}
1 Like

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.

  1. Create a Blueprint version of the camera director by right clicking the class and making a blueprint version.
  2. Delete the old Camera Director in the scene and replace it with the Blueprint version.
  3. 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.

Hello. Same problem here. Suggested solutions don’t work.

My header file:

// 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"

USTRUCT(BlueprintType)
struct FCameraHolder
{
	GENERATED_BODY()
		
	UPROPERTY(EditAnywhere)
	AActor* Camera;

	UPROPERTY(EditAnywhere)
	float TimeToNextChange;

	UPROPERTY(EditAnywhere)
	float SmoothBlendTime;
};

UCLASS()
class HOWTO_AUTOCAMERA_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)
		AActor* CameraOne;

	UPROPERTY(EditAnywhere)
		AActor* CameraTwo;

	UPROPERTY(EditAnywhere)
		TArray <AActor*> Cameras;

	UPROPERTY(EditAnywhere)
		FCameraHolder Camera0;

	UPROPERTY(EditAnywhere)
		TArray <FCameraHolder> CameraList;

	float TimeToNextCameraChange;
	int CurrentCameraNum;


	
};

Can’t edit CameraHolder structure. It doesn’t show if it’s a class field and in case of array it’s “0 members”.

I’m a complete beginner, and your solution really helped me out.

I didn’t even use a blueprint Camera Director, and it helped me to understand how the UStruct and UClasses work together.

Thanks a lot, mate.