Issue Description:
According to the documentation, the EditCondition expression used in UPROPERTY(meta = (EditCondition=“…”)) is not limited to boolean properties and can evaluate more complex expressions. However, in practice it appears that only certain types of expressions work.
For example, comparisons using bool properties or enum values work as expected, but conditions such as checking whether an FName is None do not seem to work.
Example:
UPROPERTY(EditAnywhere)
FName TestName;
UPROPERTY(EditAnywhere, meta = (EditCondition=“TestName != NAME_None”))
int32 TestValue;
Expected Result:
The property `TestValue` should only be editable when `TestName` is not NAME_None.
Actual Result:
The EditCondition does not evaluate correctly and the condition does not behave as expected.
Additional Notes:
- Bool conditions work correctly.
- Enum comparison conditions also work.
- However, checks such as FName None comparisons do not appear to be supported.(I tried TestName.IsNone() == false, TestName != None, … also)
Question:
Is this intended behavior or a current limitation of the EditCondition parser?
If it is a limitation, are there plans to support expressions like FName None checks(or others) in the future?
Hello [mention removed],
Thanks for the detailed report. I was able to reproduce this behavior locally. This appears to be a current limitation of the EditCondition expression parser rather than an issue with your usage.
The expressions used in UPROPERTY(meta = (EditCondition=“…”)) are parsed by EditConditionParser.cpp, which currently supports only a limited set of property types and comparisons, such as bool, enum, and numeric comparisons. FName comparisons are not currently supported in UE 5.6, UE 5.7, or in a recent UE5-Main source build (CL 51575875).
The editor does provide another way to achieve similar behavior through details panel customization. By creating a small Editor module and implementing an IDetailCustomization, CustomizeDetails can be used to show or hide properties based on another property’s value, including whether an FName is NAME_None. For reference, below is an example of this approach in an Editor module called ‘PropNameCaseEditor’:
// This code implements the module for the PropNameCaseEditor.
// It registers a custom detail layout for the AMyActor class, which customizes the visibility of the Offset property based on the value of the SocketName property.
// If SocketName is not None, Offset will be visible; otherwise, it will be collapsed.
#include "PropNameCaseEditor.h"
#include "Modules/ModuleManager.h"
#include "PropertyEditorModule.h"
#include "IDetailCustomization.h"
#include "DetailLayoutBuilder.h"
#include "DetailCategoryBuilder.h"
#include "IDetailPropertyRow.h"
#include "PropertyHandle.h"
#include "PropNameCase/MyActor.h"
class FMyActorCustomization : public IDetailCustomization
{
public:
static TSharedRef<IDetailCustomization> MakeInstance()
{
return MakeShared<FMyActorCustomization>();
}
virtual void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override
{
const TSharedRef<IPropertyHandle> SocketNameHandle =
DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(AMyActor, SocketName));
const TSharedRef<IPropertyHandle> OffsetHandle =
DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(AMyActor, Offset));
// hide default row
DetailBuilder.HideProperty(OffsetHandle);
IDetailCategoryBuilder& Category = DetailBuilder.EditCategory(TEXT("Test"));
IDetailPropertyRow& OffsetRow = Category.AddProperty(OffsetHandle);
OffsetRow.Visibility(
TAttribute<EVisibility>::CreateLambda([SocketNameHandle]()
{
FName Value = NAME_None;
if (SocketNameHandle->GetValue(Value) == FPropertyAccess::Success &&
Value != NAME_None)
{
return EVisibility::Visible;
}
return EVisibility::Collapsed;
}));
}
};
IMPLEMENT_MODULE(FPropNameCaseEditorModule, PropNameCaseEditor)
void FPropNameCaseEditorModule::StartupModule()
{
FPropertyEditorModule& PropertyModule =
FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
PropertyModule.RegisterCustomClassLayout(
AMyActor::StaticClass()->GetFName(),
FOnGetDetailCustomizationInstance::CreateStatic(&FMyActorCustomization::MakeInstance)
);
PropertyModule.NotifyCustomizationModuleChanged();
}
void FPropNameCaseEditorModule::ShutdownModule()
{
if (FModuleManager::Get().IsModuleLoaded("PropertyEditor"))
{
FPropertyEditorModule& PropertyModule =
FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
PropertyModule.UnregisterCustomClassLayout(AMyActor::StaticClass()->GetFName());
PropertyModule.NotifyCustomizationModuleChanged();
}
}
This example hides the Offset property when SocketName is NAME_None, which mirrors the behavior that would normally be expected from an EditCondition.

If native support for FName comparisons in EditCondition would still be useful for your workflow, this case can also be escalated as a feature request for the engine team to consider.
Please let me know.
Best,
Francisco
Alternatively, note you can always work around any limitation by setting the EditCondition to a UFUNCTION that returns a bool.
In the implementation, you can then do anything you want.
EDIT: the following actually *does not* seem to work; it would be really cool if it did though…
The error logged is:
LogEditCondition: Error: Syntax error: No operand specified for operator ‘*’
If your UPROPERTY is in a USTRUCT (and therefore cannot have UFUNCTIONs), you can still defer to a static UFUNCTION in another UCLASS, like this:
// in this example, MyStaticUFUNCTION takes the USTRUCT ‘this’ as input parameter so it can access its data
UPROPERTY(EditAnywhere, meta = (EditCondition = “MyModule.MyDummyUCLASS.MyStaticUFUNCTION(*this)”))
bool DummyUPROPERTYInAUSTRUCT;