Unreal Engine Property Edit Conditions

Article written by Jon L.

Edit Conditions Before 4.23

Each UPROPERTY declaration may have an EditCondition defined in its metadata. This edit condition controlled whether or not the property it was attached to was editable in the details view. This edit condition was a single boolean value, eg:

meta=( EditCondition="bAllowOverride" )

When bAllowOverride was true, the property would be editable:****

This condition could also be negated (!bAllowOverride), in which case the property would not be editable when the condition was true:


Since each edit condition was a single boolean, it was also simple to inline the property by adding it to the edit condition property’s meta, eg.

UPROPERTY(..., meta =(InlineEditConditionToggle)) bool bLoopPositionOverride;

Which looked like this:


However, this meant that every property that used that edit condition would duplicate that property:


This could be confusing, so it was possible to hide the inline checkbox on certain properties using the metadata tag HideEditConditionToggle on a property, eg:


This allowed for a decent amount of customization of the details view without writing a full-blown IDetailCustomization. However, a single boolean is still extremely limiting, and there are many simple things which require more expressiveness. Enter 4.23…

EditConditions After 4.23

First, all of the above still applies after 4.23!

However, the edit condition is now evaluated using a full-fledged expression parser. This allows for much more complicated expressions to be evaluated, such as:

UPROPERTY(..., meta=(EditCondition="!bEnabled || Mode != EMode::MyMode && Duration > 10"))

For more examples of valid expressions, you can peruse EditConditionParserTests.cpp. You can also play around with some examples set up by opening the console in the editor and entering the command testprops and scrolling to the Edit Conditions category. This uses PropertyEditorTestObject.h for its data if you want to inspect it.

The expression parser uses standard C++ syntax, and the full set of operators that are supported are:

==, !=, >, >=, <, <=, ||, &&, !, +, -, *, /

Note that this does not include parentheses for sub-expressions, so operator precedence matters (and is the same as in C++).

Supported types are all numeric types (both property and literals), booleans, and enums (must be defined as UENUM), ie:

uint8, ..., uint64, int8, ..., int64, float, double, bool, UENUM()

Numeric types are all converted to doubles for comparisons, so these expressions are valid:

MyFloat > MyInteger MyInteger <= 5.5

You may have noticed those arithmetic operators at the end of the operator list. That means that you can do some basic arithmetic in expressions, eg.:

MyInteger < MyFloat - 5

However, do note that these are all evaluated as doubles, so you cannot rely on integer division semantics. Eg. this will evaluate to true when MyInteger is 5:

MyInteger / 2 == 2.5

Simple boolean expressions are still compatible with inline edit condition toggles, with some additional syntaxes enabled, since these are equivalent to the previous version when evaluated, eg.:

bAllowOverride == true or false == bAllowOverride

Enum comparisons supported are equality and inequality:

MyEnum == EMode::A or MyEnum != EMode::A

For enums that are marked with the Bitflags metadata, it is also possible to use the bitwise and operator (&) to test for certain flags:

UENUM(meta=(Bitflags)) enum EBitflags { Zero = 0, One = 1 } MyEnum & EBitflags::One


Only fields of the owning class are supported. No methods or functions!

Edit conditions are evaluated every tick when the property is visible. There is no optimizer, so even constant expressions can end up being expensive, eg.

5 * 2 / 10 - 1 == 0

Enums must be namespaced, even for old-style enums, eg:

enum MyEnum { A }; TEnumAsByte<MyEnum> EnumValue; UPROPERTY(..., EditCondition="EnumValue == MyEnum::A")

Enums do not implement any comparisons other than equals and not-equals, and bitwise and for flags. Properties inside structs are not supported, even built-in structs, so this will not parse:

MyColor.R == 0

No parentheses, so this will not parse: (A || B) && (C || D)

No bitwise operators or bitshifts for integers.

Related Metadata

There are other metadata properties, related to edit conditions, which can help you set up the Details views that you want without extensive customization. Here are a few that might help you.


As the name implies, EditConditionHides says that the property’s EditCondition expression should also be used to calculate its visibility. For example:

meta=(EditCondition=”bEnabled”, EditConditionHides)



This also applies to more complex edit conditions, eg.:

meta=(EditCondition=”MyEnum == EMode::Mode2D || bEnabled”, EditConditionHides)




This can be useful for having a single checkbox to enable and display multiple properties, or have different modes with different controls, for example:



This property can also be applied in conjunction with our following metadata property to create even more customized UIs.


The InlineCategoryProperty metadata tells the Details view to hide a boolean or enum property from the default details view position it would usually be in, and instead display it in-line with the category, eg.:

UPROPERTY(EditAnywhere, Category=”My Category”, meta=(InlineCategoryProperty))



However, sometimes we want to explicitly create a UI that has different modes that are exclusively enabled. Adding the InlineCategoryProperty metadata, and EditConditionHides to our child properties:

UPROPERTY(EditAnywhere, Category=”My Category”, meta=(InlineCategoryProperty))

EMode MyMode;

UPROPERTY(EditAnywhere, Category = MyCategory, meta = (EditCondition="MyMode == EMode::Mode2D", EditConditionHides))

FVector2D MyVector2;

UPROPERTY(EditAnywhere, Category = MyCategory, meta = (EditCondition="MyMode == EMode::Mode3D", EditConditionHides))

FVector MyVector3;



While only boolean or enum properties are currently supported, this should still give you an idea of how this feature can be used to create UIs that are dynamic and feel handcrafted, but without much effort.


Hi Rudy, thanks for sharing this - there’s really soooo much valueable information, great resource.

Just a comment in case someone runs into stupid problems like me, just silently failing the condition:

This one is BAD:

UPROPERTY(EditAnywhere, Category = "Test", meta = (EditCondition = "Variable > 0.0f"))

The problem was the 0.0f - used to write my floats is as such, I did it the same in the EditCondition, but here, this little “F” turns out to be evil…

The correct one works

UPROPERTY(EditAnywhere, Category = "Test", meta = (EditCondition = "Variable > 0.0"))