Hello everyone,
few months into using UE5, our team has come across this odd behavior that makes it practically impossible to change the values of component properties in the editor’s Details Panel when these components are on instances of blueprint actors. To better illustrate this issue, I am including the steps needed to reproduce it (tested this on both version 5.0.3 and 5.1.0 Preview 2 and got the same results):
- Create a blank C++ project
- Create a C++ class that inherits from UActorComponent with an editable property. Extend its BeginPlay() function with a test log to see when the function is called.
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class MYPROJECT_API UMyActorComponent : public UActorComponent
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
int32 MyProperty;
public:
virtual void BeginPlay() override;
};
void UMyActorComponent::BeginPlay()
{
Super::BeginPlay();
UE_LOG(LogTemp, Display, TEXT("UMyActorComponent's BeginPlay() called!"));
}
- Create a C++ class that inherits from AActor with a property that holds an instance of the previously created component. Extend the constructor of the class with the creation of this instance using CreateDefaultSubobject().
UCLASS()
class MYPROJECT_API AMyActor : public AActor
{
GENERATED_BODY()
public:
UPROPERTY(VisibleAnywhere)
TObjectPtr<UMyActorComponent> MyActorComponent;
public:
AMyActor();
};
AMyActor::AMyActor()
{
MyActorComponent = CreateDefaultSubobject<UMyActorComponent>(TEXT("MyActorComponent"));
}
- Run the engine and create a new level.
- Create a blueprint class that inherits from Actor and add the previously created component to it using the Add new component button in the Components Tab.
- Add these actors into the created level:
a. One instance of the blueprint class actor.
b. One instance of the C++ based actor.
c. One instance of the basic empty actor. Add the previously created component to it through the Add new component button in its Details Panel. - Save all changes and start a PIE session. Observe that all three components output a log message in the Output Log window as expected.
- Select either the C++ based actor or the basic template actor. Select the component in the Details Panel and change the value of its property. Observe that the value changes as expected and no log messages are created.
- Do the same with the blueprint based actor. Observe that the change leads to the component outputting another log message.
Basically, what happens here is that for some reason changing property values in a blueprint actor’s components causes it to throw away and completely recreate all of its components. This would be even more noticeable if we were to add another component to the actors that also outputs a log message on BeginPlay. This component would also produce a log message on the blueprint actor despite us not even touching it. This is how we have originally come across this issue when it would reset animations on skeletal meshes.
What’s also weird is that the change gets applied on the recreated component. In some cases we would encounter that changing nested object’s properties inside the component would reset the changed property’s value. In the test example, this can be achieved by marking the property as Transient.
The issue applies to both actor and scene components, regardless of whether the component itself is C++ or blueprint based. We have also not been able to find any UCLASS or UPROPERTY specifier, nor an option in the blueprint details that would fix this. Then again, we are fairly new to the engine so we have not had the time to delve deep into the whole CDO ecosystem and similar behind-the-scenes engine details.
Is this the expected behavior or indeed a bug? It would be weird if this was intended as it would limit our ability to test and iterate, or limit the usability of blueprints. On the other hand, I have not been able to find any forum posts or bug reports regarding this so we might be missing something obvious. Any help is greatly appreciated.