Sponsored By

UE4Cookery CPP006: Instanced UProps

Topic: Instanced UProps

Source for UE4.26: https://github.com/klauth86/UE4Cookery/tree/main/CPP006

Artur Kh, Blogger

March 16, 2021

2 Min Read

At some point of developing project, one can face the problem of using class hierarchy inside one UProperty. Suppose that you are trying to implement your own game event system, where some actors will have list of game events to fire on some action. You gonna want to edit and create those game events in Editor. At the beginning there will be only several types of game events and you may choose to keep only one struct to store all different game events data. But as number of different game event types will grow, this approach will surely begin suffering from ineffective data storage - too much fields will be unused for every game event type. At this moment you will turn to use class hierarchy around some base class. So, having UProperty of this base class pointer, how can we implement all that was mentioned? For this case there is Instanced property specifier that allows you to create instances in Editor and set UProperty pointer to it. Let's construct some basic example project!

 

First of all, we need some class hierarchy. It may be something like this:

 

MyObject_Base.h


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "UObject/NoExportTypes.h"
#include "MyObject_Base.generated.h"

UCLASS(Abstract, BlueprintType, EditInlineNew)
class CPP006_API UMyObject_Base : public UObject
{
	GENERATED_BODY()
	
};

 

and its two subclasses

 

MyObject_A.h


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "MyObject_Base.h"
#include "MyObject_A.generated.h"

UCLASS()
class CPP006_API UMyObject_A : public UMyObject_Base
{
	GENERATED_BODY()

protected:

	UPROPERTY(EditAnywhere)
		FString MyString = "Hello A!";
};

 

MyObject_B.h


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "MyObject_Base.h"
#include "MyObject_B.generated.h"

UCLASS()
class CPP006_API UMyObject_B : public UMyObject_Base
{
	GENERATED_BODY()
	
protected:

	UPROPERTY(EditAnywhere)
	uint8 MyIntProp = 0;
};

 

Pay attention to Abstract and EditInlineNew class specifiers. The first one declares our base class as abstract, so no instance of it can be created. The second allows you to edit instance that is created in Editor.

Now, we will create AActor, that contains base class pointer UProperty and even TArray of base class pointer UProperty. It will be

 

MyActor.h


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Actor.h"
#include "MyActor.generated.h"

class UMyObject_Base;

UCLASS()
class CPP006_API AMyActor : public AActor
{
	GENERATED_BODY()

protected:

	UPROPERTY(EditAnywhere, Category = "My Actor", meta = (ShowOnlyInnerProperties), Instanced)
		UMyObject_Base* MyObj;

	UPROPERTY(EditAnywhere, Category = "My Actor", meta = (ShowOnlyInnerProperties), Instanced)
		TArray<UMyObject_Base*> MyObjArray;
};

 

That is all we need. In Blueprint Editor, we will discover all stuff to create, remove and edit instances of class hierarchy:

 

Instanced UProps in Blueprint Editor

 

Note, that there is no any abstract class in list.

Read more about:

Blogs

About the Author(s)

Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like