Download

Property editable TArray of different types (or equivalent)

Hey all.

Need a bit of help thinking in UE-ese :slight_smile:

I need a “command list” which is a list of commands to be fed to an AI squad or individual. So I’m thinking that what I’d need is a TArray, that has references to varying classes.

What I’m after, is something like the perception components “sensesconfig” setup. Where you can add different types of classes that are inherited from the same base class and edit them as individual instances.

The problem is that sensesconfig is EditDefaultsOnly and I need the same kind of thing to work on Actors that are setup in the level, not archetypes stored as assets.

So I guess this is a multipronged questionette: 1) How do you get something like sensesconfig of perceptioncomponent to work with similar editing properties but on instances dragged into a world and 2) How do you associate the derived classes with the base class in such a way that the dropdown shows the derived classes properly?

I’m guessing its some specifier-fu in the UPROPERTY declaration if anything.

Anyone care to comment?

Ta.

EditAnywhere will allow it to be edited on instances.

TSubClassOf<YourBaseClase> type of variable will give you a drop-down showing subclasses of YourBaseClass.

That’s not quite it. If you add EditAnywhere, the properties themselves become uneditable. The TSubClassOf doesn’t help me as I need to create an instance of the class, not refer to one. As I said, it works if you mark it up as “EditDefaultsOnly” as per the Sense class code. But once you mark it as EditAnywhere, that editability goes away.

If I understand right, you need this:



UCLASS(Abstract, EditInlineNew)
class UCommandBase: public UObject
{
...
};

// In some other class
UPROPERTY(Instanced, EditAnywhere, ...)
TArray< UCommandBase* > CommandList;


How do you even know this stuff Kamrann? :slight_smile:

ALMOST THERE. Unfortunately this means it is editable in the blueprint, but not in an instance of that blueprint in the level. What I need, is to be able to edit individuals command lists prior to running the AI. So this editing interface needs to be exposed to actors I’ve dragged out into a level with different data. Not on the archetype class.

Anything I can do to achieve that?

I would have expected that to work fine. Are you sure you’ve used EditAnywhere on the array?

Yep, I’ve tried EditAnywhere and EditInstanced and same deal. Only editable on the archetype and not on the instance of it.

How does it appear in the details panel on an instance in the level?

I’ve done this myself and it’s worked as I expected. Maybe post up all the relevant code if you want and I’ll see if I can spot anything different.

In the instance it basically shows whatever is shown on the archetype. So if I edit the archetype I see the changes on the instances. Instances aren’t editable at all.

Here’s the code, thanks for having a look:



UCLASS(Abstract, EditInlineNew)
class UCommandBase : public UObject
{
	GENERATED_BODY()
public:
	UPROPERTY(EditAnywhere, Category = "Command")
	FString Name = TEXT("Commandbase");
	UPROPERTY(EditAnywhere, Category = "Command")
	float Priority;
};

UCLASS()
class UCommandAttack : public UCommandBase
{
	GENERATED_BODY()
public:
	UPROPERTY(EditAnywhere, Category = "Command")
	FVector AttackLocation;
};

UCLASS()
class UCommandDefend : public UCommandBase
{
	GENERATED_BODY()
public:
	UPROPERTY(EditAnywhere, Category = "Command")
	FVector DefendLocation;
};



And for the component declaration:



	UPROPERTY(EditAnywhere, Instanced, Category = "Argh")
	TArray<UCommandBase *> Commands;


Should just say… the properties are editable just fine in the archetype. So if I can just get the exact same usage to work per-instance I’d be a happy camper.

Ah, your command array is on a component? I think I know what this is, you’ve added the component in a blueprint rather than in a C++ constructor, right?

I’ve seen some stuff like this before, there are frankly all sorts of things that start going wrong when you try to do anything a bit non-standard with components and instanced properties.
I’m guessing in the instance, the properties aren’t grayed out, but when you try to change anything it just ignores the change? If so, it’s because any property change reruns the construction script, which includes destruction and recreation of all components that were added in blueprint. The engine handles saving and reapplying changes you made to the newly created component, but it doesn’t seem to be able to do it automatically when it comes to instanced subobjects. So the new component just gets reinitialized with the subobjects defined in it’s archetype, losing the modification you just made.

I think, but I’m not sure, that this particular issue is intended behaviour and not a bug. I believe you can handle cases like this by overriding UActorComponent::GetComponentInstanceData - have a look in the engine codebase for examples of it being done. I’ve never tried though, not sure how involved it is.

Much easier fix is to just always create the component in C++ constructor and not have it blueprint spawnable, but depending on your plans that may be too big a restriction.

Thanks a load Kamrann! I can understand exactly what this issue is now. I’ve actually had issues with this kind of thing elsewhere, only with the opposite effect (incorrectly displaying properties in C++ component, but works fine on blueprint added one of the same class).

FML :slight_smile: thanks for the info though, I’ll have a quick check and see what happens if its added on a C++ version. Strangely enough, I think it might be OK as we’re likely to be using these classes on C++ based components. I was just testing on a blueprint version to see if I could get it working.