How do I enable/disable controls in my blueprint details panel via C++?

I have a C++ project which creates a few blueprints in code. I have exposed some of my class properties to the engine via the UPROPERTY macro. I want to be able to enable / disable certain controls based on the state of other controls, similar to how the Collision details component enables / disables check boxes when you change the Collision Presets drop down menu value to “custom”.

How and where do I create this UI logic in my C++ code? Is it possible?

Example use case:
I have a unit formation which can be defined either by a fixed number of rows and columns, or it can be defined by an enclosing bounding box. If you want the bounding box region to define the number of rows and columns for the unit formation, you should be able to toggle a check box. If instead you want to manually set the number of rows and columns and let the bounding box be a placement guide for the top left position of the formation, you should be able to do this as well. However, you can’t do both. So, the UI should disable certain controls to reflect this logic.

If your logic to enable/disable certain properties can be boiled down to a simple bool member, then you have an easy way out: EditCondition.


UPROPERTY( Category=Location, EditAnywhere )
uint32 bUseOffset:1;

UPROPERTY( Category=Location, EditAnywhere, meta=(EditCondition="bUseOffset") )
FVector Offset;

This will make the Offset property only editable if bUseOffset is checked. You can negate EditConditions:


UPROPERTY( Category=Location, EditAnywhere )
uint32 bAutoOffset:1;

UPROPERTY( Category=Location, EditAnywhere, meta=(EditCondition="!bAutoOffset") )
FVector ManualOffset;

But you cannot use expressions, even if they evaluate as bool:


UPROPERTY( Category=Location, EditAnywhere )
int32 SomeCounter;

UPROPERTY( Category=Location, EditAnywhere, meta=(EditCondition="SomeCounter != 0") )
FVector Offset;

If you need something more complex than simple bools, editor customization is what you’re looking for. And that is a very rich and complex topic that wouldn’t really fit in a single post.

I did very briefly broach the subject in a different post, which might help you get started if you want to go down that rabbit hole. The general idea is that you register an editor customization for the class you want, then implement the matching interface in order to change the way properties are displayed. It’s not an easy thing but there are lots of examples in the editor you can base yourself from, just like the collision presets.

7 Likes

:

This is a hugely useful piece of information. Thank you for sharing!

I was reading a few other posts on EditCondition and found a way to edit properties which don’t rely on a boolean value and instead can use an expression which evaluates to true/false:

Within your class header file, you have to override “CanEditChange()”:



virtual bool CanEditChange(const UProperty* InProperty) const override;


Within your CPP file, you have to create a custom implementation for CanEditChange():



bool [YOURCLASSNAME]::CanEditChange(const UProperty* InProperty) const
{
	const bool ParentVal = Super::CanEditChange(InProperty);

	//show the projectile type dropdown only if the delivery method is projecile
	if (InProperty->GetFName() == GET_MEMBER_NAME_CHECKED([YOURCLASSNAME], [CLASS VARIABLE WITH UPROPERTY MACRO]))
		return ParentVal && /*[INSERT BOOLEAN EXPRESSION(S)]*/;
        /*Add any "else if" chains here.*/
	else
		return ParentVal;
}


With this, you don’t have to use EditCondition as a meta specifier!

Note that this just disables the properties within the editor, it does nothing to the actual values in your class. Someone can enable a property, change it in the details, and then disable it and the value is still there. In these cases, you’ll want to reset the value in either the CDO or the construction script.

3 Likes

Any way to do this in blueprints without c++ code?

Nope, you gotta use C++.

Info in this thread is out of date. You can use fairly complex boolean expressions in EditCondition as of UE 4.23; E.g.


UPROPERTY(EditAnywhere, meta=(
    EditCondition="SomeEnumProperty == EMyEnum::Foo && !bBoolProperty || SomeIntProperty < 3"))

Integer and float comparisons work (equality, greater/less-than) as does enum equality. You can combine with && and ||. The only major flaw I’ve found is it doesn’t seem to be able to handle parentheses in the expression, and bad expressions may compile, but fail at runtime (either crashing or just always evaluating to true).

You can also hide properties using the EditCondition as of 4.24! Just add the EditConditionHides meta tag:


UPROPERTY(EditAnywhere, meta=(EditCondition="bBoolProperty", EditConditionHides))

7 Likes

is it possible to hide property if return is false?