How to expose UObject variables from C++ to Blueprints

As the title suggests, I’d like to know how to expose UObject variables from C++ to Blueprints in the details panel. Just like how you can expose an int or a bool by using the UPROPERTY Macro, I’d like to do the same for UObject variables such as UChildActorComponent. If I try using UPROPERTY(EditAnywhere) for a UChildActorComponent it won’t work, similarly if I also add the BlueprintReadWrite attribute it won’t appear in the details panel, although I can still access it and edit it in the blueprints. How can I go about this? Thanks!

Example uobject class

MyObject header

#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "MyObject.generated.h"

/**
 * 
 */
UCLASS()
class YOURPROJECT_API UMyObject : public UObject
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere,BlueprintReadWrite)
	float myNumber;
};

MyObject cpp only includes header #include "MyObject.h"

Object that holds it in it’s details panel

MyActor2 header

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor2.generated.h"

UCLASS()
class LINETRACEPROJECT_API AMyActor2 : public AActor
{
	GENERATED_BODY()
	
public:	
	
	AMyActor2();

	UPROPERTY(EditAnywhere , BlueprintReadWrite, Instanced)
	class UMyObject* Obj;

};

MyActor2 cpp


#include "MyActor2.h"
#include "MyObject.h"

AMyActor2::AMyActor2()
{ 	
	PrimaryActorTick.bCanEverTick = false;
	Obj = CreateDefaultSubobject<UMyObject>(TEXT("my object"));
}

detail_inline

I apologize if I am unable to understand, I’m not very experienced. But how can I do this with a USpotLightComponent for example?
I tried this but failed (it is in public):

UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced)
		class USpotLightComponent* SpotLightComponent;

It should work, I just tested it out in a scene

just be sure to initialize it in the cdo

AMyExampleClass::AMyExampleClass()
{

SpotLightComponent = CreateDefaultSubobject<USpotLightComponent>(TEXT("Spot Light Component"));
// if its in a hierarchy (as a child)
SpotLightComponent->SetupAttachment(YourParentSceneNode); // <== attach to whatever you need here 

Ah, I didn’t initialize it. But even when I did using this code:

SceneComponent = CreateDefaultSubobject<USceneComponent>TEXT("SceneComponent"));
SetRootComponent(SceneComponent);
SpotLightComponent = CreateDefaultSubobject<USpotLightComponent>(TEXT("Spot Light Component"));

It still wouldn’t show the variable despite the Spot Light Component showing in the hierarchy.

Add

SpotLightComponent->SetupAttachment(GetRootComponent());

and it will attach it to root. Also make sure to recompile you project (avoid the live edit tool, it doesn’t update big changes in the code)

Still doesn’t work. I’m not sure what to do now.

Please post the code for the header and cpp file and I’ll take a look

SecurityCamera.h:

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/SpotLightComponent.h"
#include "SecurityCamera.generated.h"

UENUM(BlueprintType)
enum class ESecurityCameraType : uint8
{
	Classic UMETA(DisplayName = "Classic"),
	Night UMETA(DisplayName = "Night"),
	Thermal UMETA(DisplayName = "Thermal")
};

UCLASS()
class TESTINGGAME_API ASecurityCamera : public AActor
{
	GENERATED_BODY()
	
public:	
	ASecurityCamera();

protected:
	virtual void BeginPlay() override;

public:	
	virtual void Tick(float DeltaTime) override;

	// Security Camera
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Security Camera")
		TSet<ESecurityCameraType> CameraTypes;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Security Camera")
		int CameraGivenID;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Security Camera")
		bool IsAccessible;

	// Flashlight
	UPROPERTY(BlueprintReadOnly, Category = "Flashlight")
		bool IsFlashlightOn;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Flashlight")
		class USpotLightComponent* SpotLightComponent;

private:
	class USceneComponent* SceneComponent;
};

SecurityCamera.cpp:

#include "SecurityCamera.h"

ASecurityCamera::ASecurityCamera()
{
	PrimaryActorTick.bCanEverTick = false;
	SceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("SceneComponent"));
	SetRootComponent(SceneComponent);
	SpotLightComponent = CreateDefaultSubobject<USpotLightComponent>(TEXT("Spot Light Component"));
	SpotLightComponent->SetupAttachment(GetRootComponent());
}

void ASecurityCamera::BeginPlay()
{
	Super::BeginPlay();
}

void ASecurityCamera::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

You forward declared the SpotLightComponent in the header but forgot to add the include in the cpp file

your includes in SecurityCamera.cpp should look like this:

#include "SecurityCamera.h"
#include "Components/SpotLightComponent.h" 

It compiles no problem and shows up in the details panel

Always check the needed Modules & includes :slight_smile:

Ah thank you! Now it works. I greatly appreciate it. It turns out its because of not initializing.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.