Removing the EditAnywhere specifier from a variable doesn't discard the value assigned to it in the editor

When creating an variable with the EditAnywhere specifier, and later on removing that specifier, the value that was assigned to it in the editor remains valid.

Steps to reproduce :

  • Create a new C++ based 4.10.1 project

  • Create a new C++ class (or modify one of the existing ones)

  • Add a public variable with the following specifiers to your class:

    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = “Test”)
    TArray TestArray;

  • Create an actor deriving from the C++ class

  • In the actor details panel, assign values inside TestArray

  • Remove the EditAnywhere specifier and recompile.

  • Note that TestArray is no longer editable through the actor’s detail panel

  • Inside the actor’s blueprint, inspect the length of TestArray

  • Note that length is not 0 as expected, and that TestArray still contains the actors previously assigned to it.

Hello,

This is expected behavior. When you have the EditAnywhere specifier and set values, deleting that specifier will not remove any of the values that you set while the specifier was active.

Have a great day,

Sean Flint

Hi Sean.
I was wondering what is the reasoning behind this behavior, as it could lead to some unexpected results in a large scale project.
This behavior means that for any property that you no longer wish to be exposed in editor, nor remember the value that was assigned in editor, you must write up the functionality to confirm that the property does not contain any unexpected values (or delete the property altogether, and create a new one of the same type).
Is this the appropriate solution for when the design changes and a property should no longer be exposed?

Could you explain what sort of problems this could cause in your project?

The issue that made us discover this behavior could be seen as a problem, especially as we were not aware of this behavior.

We had an array of actors, initially designed to be exposed in editor and have actors dragged in. later on in development we had decided exposing the array in editor is no longer necessary and decided to populate the array through code (by a tag search, in this particular case). Not being aware of this behavior meant that the array now contained actors that did not match the tag, and initially we didn’t know how they got there.

Surely this is easily fixed by either making sure the variables are unassigned in editor before removing the EditAnywhere Specifier, or using a completely new variable whenever the design indicates that exposing to editor is no longer necessary. However we were mostly curious as to what stands behind the decision to implement this behavior, as we cant think of a case where this would be desired behavior.

We encountered this issue as well. This is a serious issue as we can’t trust the state of the object by looking at the data and code! There appears some state to be lingering out of the reach of the developer and without the tools to inspect or address this.

Fixing this might break projects depending on this, faulty, behavior but that should never be the reason to do the right thing.

A manual way to clean all the uassets with this lingering state would be a nice addition for those encountering this issue. Is this something you could let the developers look into?

Cheers!

Hello,

If I’m understanding it correctly, you are experiencing the same issue that Drorza reported in this original post. The reason for this behavior is that once you set the default value for a variable that is marked as EditAnywhere, removing that specifier will not remove the default value, and this is by design. Removing the specifier will only prevent the variable from being edited in a blueprint, but will not clear it of all values that were set while it was marked as EditAnywhere.

Have a great day