BP based on C++ class does not reset a component's defaults

Either I’m missing something or it’s a bug.

What I did:

  1. Made a PlayerCharacter C++ class
  2. Made a blueprint based on such c++ class (PlayerBP)
  3. Added a WidgetComponent to the C++ PlayerCharacter with UPROPERTY(EditDefaultsOnly)
  4. In PlayerBP changed WidgetComponent’s Location
  5. In PlayerCharacter C++ removed EditDefaultsOnly (to disable possibility to change the component’s parameters)
  6. In PlayerBP I see the component but can’t see or change any parameters
  7. When start the game, the component has Location which I set manually when it has EditDefaultsOnly
  8. After cleaning temporary files and complete rebuild/recompile it still has such Location and I don’t see a way to reset it to default parameters (from C++ class)

UPDATE:
I’ve added EditDefaultsOnly again and after reset the Location to the defaults, it still use the same location (which I set manually at the first time). And even if I change the Location to any values it still use the old value from somewhere. It has this weird location from the very beginning, I’ve printed it out from Constructor script, and from BeginPlay.

I have no idea from where it goes… Is there any way to open a blueprint as a code, to check find this value?

Hi norlin,

Sorry for not responding sooner to your post. I looked into the issue that you described, and I believe everything here is actually working correctly. If you add a component to a class with the EditDefaultsOnly specifier, then create a Blueprint of the class and modify the component’s values, those changes will persist in the Blueprint even if you later remove the EditDefaultsOnly specifier. If you want the component’s values to reset to the default values after removing the EditDefaultsOnly specifier, you would need to create a new Blueprint.

I am somewhat unsure about what you were seeing in the “update” section of your post. I added the EditDefaultsOnly specifier back into the parent class, and then changed the Location of the component again and the component would then use the new Location that I had set (this was in 4.18.3, so it may have been an issue that has been fixed since you noticed it).

those changes will persist in the Blueprint even if you later remove the EditDefaultsOnly specifier.

I’m sure it’s a bug since it makes serious inconsistency – Blueprint is inherited from specific class, but in that case it acts somehow different (c++ class does not allow to set the values from BP yet BP uses custom values).

about the second part – I will re-check it in 4.18.3

It may seem like an inconsistency on the surface, but it actually is not. If the default values for a component are changed in a Blueprint, and then the ability to change those default values is removed, the values would not get reset to their original value from when the Blueprint was first created. The changed values would be retained in that Blueprint, but it would not be possible to further adjust them without adding the ability to change those values back in. If you were to add the ability to change the values back to the parent class, any values that had been changed the first time would still show their changed values and not the original values from when the Blueprint had first been created.

This is intentional behavior, since it allows you to change the default values in a Blueprint and then prevent any further accidental changes by removing the ability to edit the values. If any additional changes need to be made, you can add the ability to edit the values back into the parent class. If you wanted some or all of the values to be reset to their original defaults, you would need to make them editable and click the “Reset To Default” arrow for each one, or create a new Blueprint which would be created with the original default values.

Hmm, ok, probably it’s required for some reson, but this is exactly what I’m calling “inconsistency”:

The changed values would be retained in that Blueprint, but it would not be possible to further adjust them

If the member of the class was overridden in the blueprint – then it still should be possible to change it. But if it’s inherited from the parent c++ class – it should obey this class even when it was changed. That’s how inheritence usually works…

At least, it should be described somehow explicitly, as well as it should be possible to reset the values to the parent’s defaults in any case (without manually re-adding the specifier).

Blueprint inheritance from a parent C++ class is mostly similar to normal C++ inheritance, but there are a few specific differences. In a standard C++ child class, if the access specifier of a property in the parent class is changed so the property is no longer accessible to the child class, the child would not be able to override the property (without using a setter function). In that case, the default value of the property would revert back to the value set in the parent class.

However, for Blueprints the default value that was set in the Blueprint (effectively the child class) is still stored on disk even if the property is no longer exposed to Blueprints (eg. the EditDefaultsOnly specifier is removed), and will still override the default value in the parent class. It is part of the intended functionality of Blueprints. The only way to reset this value to the default value in the parent class would be to make the property exposed to Blueprints again. You could also remove the property from the parent class, compile the project, then add the property back in and compile the project again.