Download

Greying out blueprint exposed defaults?

Solved, see below :slight_smile:

Hey all, I have a number of blueprint exposed variables in C++ that are coupled in functionality, for example like this:



UPROPERTY(EditAnywhere, Category = "Default")
bool IsDestructible;

UPROPERTY(EditAnywhere, Category = "Default")
float MaxHealth;


In the editor, I want MaxHealth to be greyed out as field if IsDestructible is set to false, to make it clear for other team members. Does anyone know of a way to set this up in C++?

I want to achieve the same function!
Before I know the answer, I had to put all the inter-related properties in the construction function and give an invalid value to the property I want to “disable”(sth. like: if(!IsDestructible){MaxHealth = -1;}).
Graying out is much better than my current solution, because it will took some time before I explained what are all the “Invalid” values to all the team members.

Found it! You have to override UObject::CanEditChange() in your actor’s CPP class.

Example .h:



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


Example .cpp:



bool MyActor::CanEditChange(const UProperty* InProperty) const
{
	const bool ParentVal = Super::CanEditChange(InProperty);
	if (InProperty->GetName() == FString("MaxHealth"))
		return ParentVal && IsDestructable;
	else
		return ParentVal;
}


You saved me ! Thank you so much!

Glad it was useful to someone else as well. :slight_smile:

For simple bool checks like this, there’s an easier way to do it: EditCondition.


UPROPERTY(EditAnywhere, Category = "Default")
bool IsDestructible;

UPROPERTY(EditAnywhere, Category = "Default", meta=( EditCondition="bIsDestructible" ))
float MaxHealth;

But it has to be a simple bool variable. Even a bool expression like “SomeVariable>100.0f” won’t work.

Also, when referring to members by name, there’s a useful macro in the engine to make sure that member exists: GET_MEMBER_NAME_CHECKED. If you rename the variable for whatever reason later on, any attempts to use the variable by name will fail to compile, letting you know where you need to update them.


bool MyActor::CanEditChange(const UProperty* InProperty) const
{
	const bool ParentVal = Super::CanEditChange(InProperty);
	if (InProperty->GetFName() == GET_MEMBER_NAME_CHECKED(MyActor, MaxHealth))
		return ParentVal && IsDestructible;
	else
		return ParentVal;
}

Lastly, never ever compare by FString when you can compare by FName. FString comparisons have to compare each character in the string, but FNames use a special hashing mechanic to allow much faster comparisons.

-Camille

Lovely, the more you know. :slight_smile:

Is it possible to do this through blueprints? I am working on a blueprint only project. This issue is not a stopper for me, but it will be nice if I can add that eye candy through bluepritns :slight_smile:

Don’t think it’s possible with just blueprints, no. Might be a potential feature, the new(ish) EditCondition UPROPERTY field is pretty powerful - wonder if that could be exposed in the BP editor.